//========================================================================
//  SE5 AI Enemy Analysis - Captain Kwok's Balance Mod v125+
//========================================================================
//
// 1. Determine other player's planet/atmosphere types
// 2. Compare score to other players
// 3. Calculate fear level based on score comparison
// 4. Determine the priority against other players
// 5. Calculate our state modifier
// 6. Analyze enemy designs
// 7. Estimate other player's production
// 8. Analyze combat performance against other players
//
// Balance Mod Changes:
// --------------------
// v1.29 Changed - Mega Evil and AI team mode status now considered in AI target priority and strategy point calculations
//       Changed - Replaced Fx[Estimate_Enemy_Score_Factor] with Fx[Estimate_Player_Score] that is a more accurate score calculation to the in-game score
//       Changed - Re-vamped Fx[Analyze_Enemy_Production] to be based on the median value of all players; Neutral players skip this comparison (and are not used for calculations)
//       Added   - New Fx[Are_Our_Friends_Enemies_Of_Another_Friend] to return true when we have a friend that is an enemy of one of other friends
// v1.28 Changed - Added extra emphasis for AI players to note skip armor, skip shield, or skip all damage types from their primary enemies
// v1.27 Changed - For enemy design analyze an obsolete design type won't be skipped unless it's old as well
//       Fixed   - The modifier for primary enemy/primary combat enemy was not being applied since design analyze routine ran before this determination is made (moved design analysis after)
// v1.25 Added   - New Fx[Analyze_Enemy_Colonization_Potential] to record each player's colonization capability
//       Changed - Updated Fx[Compute_Target_Priorities] to include colonization potential as a component
//       Added   - New Fx[Analyze_Enemy_Proximity] to estimate the general proximity of other players
//       Added   - New Fx[Compute_Cooperation_Level] to determine the level of cooperation with other players
//       Added   - New Fx[Compatible_AI_Categorization] to compare similarity of AI category
//       Changed - Adjusted fear calculation to include average system distance between players
//       Changed - Several improvements in the AI's analysis of other ship designs
// v1.23 Fixed   - AI players were counting enemy designs with skip all weapons correctly
// v1.20 Changed - Updated Fx[Analyze_Combat_Performance] to allow for combat performance evaluation against individual players
//       Added   - Tracking of highest target priority weaker player
// v1.19 Added   - More specific enemy design checks for long range seeker weapons (v1.19g)
//       Changed - AI's war and treaty count is done concurrently with target priority calculations (v1.19h)
//       Added   - Fx[Analyze_Combat_Performance] to track combat record (v1.19h)
//       Added   - Checks for enemy sensor usage (v1.19j)
//       Fixed   - Error in enemy production estimates (v1.19j)
//       Changed - Made improvements in enemy resource and point production comparisons (v1.19j)
// v1.15 Changed - Expanded priority analysis to consider player's government and society types
//       Added   - New Fx[Is_Empire_Friends_With_Enemies]
//       Changed - Expanded AI's enemy design analysis
//       Added   - New Fx[Analyze_Enemy_Production]
//       Added   - New Fx[Estimate_Enemy_Score_Factor] to approximate enemy scores when they are not available
// v1.14 Added   - New Fx[Analyze_Enemy_Designs]
// v1.12 Added   - Calculations for fear and score comparison versus Alliances
//       Added   - New Fx[Compute_Target_Priorities] to determine most critical enemies
//       Changed - Move Fx[Get_Number_Of_Wars] to Script_AI_Enemy_Analysis
// v1.11 Changed - Tweaked the calculated for the AI's state modifier
// v1.10 Added   - Move Fx[Compute_State_Modifier] from Script_AI_StateChange.txt
//       Added   - Support for Alliances
// v1.08 Changed - Small changes to calculation for fear
// v1.07 Fixed   - Enemy Analysis minister does not need to be on for some functions
//       Changed - Modified fear calculation in Fx[Compute_Fear]
// v1.06 Changed - Moved Fx[Compare_Score] from Script_AI_Politics.txt
//       Changed - Moved Fx[Compute_Fear] from Script_AI_Politics.txt
//
// Balance Mod To-Do List:
// -----------------------
// - Pending
//
//
// Script Function Requests:
// -------------------------
// - Nothing pending

//------------------------------------------------------------------------
// Forward Declarations
//------------------------------------------------------------------------
deffunc

function Estimate_Player_Score returns real
params
  target_plr:                long
end

function Is_Empire_Friends_With_Enemies returns boolean
params
  target_plr:                long
end

function Are_Our_Friends_Enemies_Of_Another_Friend returns boolean
params
  target_plr:                long
end

function Compatible_AI_Categorization returns long
params
  target_plr:                long
end


function Compatible_Government_Types returns long
params
  target_plr:                long
end

function Compatible_Society_Types returns long
params
  target_plr:                long
end

function Compare_Score returns boolean
params
end

function Compute_Fear returns boolean
params
end

function Compute_Target_Priorities returns boolean
params
end

function Compute_State_Modifier returns boolean
params
end

function Compute_Cooperation_Level returns boolean
params
end

function Analyze_Enemy_Colonization_Potential returns boolean
params
end

function Analyze_Enemy_Proximity returns boolean
params
end

function Analyze_Enemy_Production returns boolean
params
end

function Analyze_Enemy_Designs returns boolean
params
end

function Analyze_Combat_Performance returns boolean
params
end

enddeffunc

//------------------------------------------------------------------------
// AI_EnemyAnalysis
//------------------------------------------------------------------------
function AI_EnemyAnalysis returns boolean
begin

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "---------------")
  call Sys_Debug_Print("Enemy Analysis", "Enemy Analysis:")

  // Analyze the other empires
  if Sys_Using_AI_Minister(sys_long_Player_ID, "Enemy Analysis") then
    call Analyze_Enemy_Colonization_Potential()
    call Analyze_Enemy_Proximity()
    call Analyze_Enemy_Production()
    call Analyze_Combat_Performance()
  endif

  // Make comparisons
  call Compare_Score()
  call Compute_Fear()
  call Compute_Target_Priorities()
  call Compute_State_Modifier()
  call Compute_Cooperation_Level()

  // Analyze vehicle designs
  if Sys_Using_AI_Minister(sys_long_Player_ID, "Enemy Analysis") then
    call Analyze_Enemy_Designs()
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Estimate_Player_Score
//------------------------------------------------------------------------
function Estimate_Player_Score returns real
params
  target_plr:                long
vars
  num_colonies:              long
  num_population:            long
  num_facilities:            long
  num_resources:             resources
  num_minerals:              real
  num_organics:              real
  num_radioactives:          real
  num_minerals_produced:     real
  num_organics_produced:     real
  num_radioactives_produced: real
  num_research_pts:          long
  num_tech_levels:           long
  num_intel_pts:             long
  num_designs:               long
  design_index:              long
  design_type:               string
  design_id:                 long
  design_count:              long
  design_cost:               resources
  lst_design_type_counted:   stringlist
  total_design_cost:         real
  total_ship_cost:           real
  total_ship_cost_mod:       real := 1.0
  total_unit_cost:           real
  total_unit_cost_mod:       real := 1.0
  is_ship:                   boolean := TRUE
  is_unit:                   boolean := FALSE
  player_score:              real
begin

  // Get the target player's basic details
  set num_colonies := Sys_Get_Player_Colonies_Count(target_plr)
  set num_population := Sys_AI_Empire_Stats_Get_Colonies_Statistics(target_plr, COLONIES_STATS_FILTER_TOTAL_POPULATION)
  set num_facilities := Sys_AI_Empire_Stats_Get_Colonies_Statistics(target_plr, COLONIES_STATS_FILTER_NUM_FACILITIES)

  // Stored resources
  set num_resources := Sys_AI_Empire_Stats_Get_Current_Resources(target_plr)
  set num_minerals := num_resources.get(RESOURCE_TYPE_MINERALS)
  set num_organics := num_resources.get(RESOURCE_TYPE_ORGANICS)
  set num_radioactives := num_resources.get(RESOURCE_TYPE_RADIOACTIVES)

  // Produced 
  set num_minerals_produced := Sys_AI_Empire_Stats_Get_Colonies_Statistics_Real(target_plr, COLONIES_STATS_FILTER_TOTAL_POINTS_PRODUCED_MINERALS)
  set num_organics_produced := Sys_AI_Empire_Stats_Get_Colonies_Statistics_Real(target_plr, COLONIES_STATS_FILTER_TOTAL_POINTS_PRODUCED_ORGANICS)
  set num_radioactives_produced := Sys_AI_Empire_Stats_Get_Colonies_Statistics_Real(target_plr, COLONIES_STATS_FILTER_TOTAL_POINTS_PRODUCED_RADIOACTIVES)

  // Points produced
  set num_research_pts := Sys_Get_Empire_Current_Points(target_plr, POINT_TYPE_RESEARCH)
  set num_tech_levels := lst_Politics_Player_Tech_Levels.get(target_plr)
  set num_intel_pts := Sys_Get_Empire_Current_Points(target_plr, POINT_TYPE_INTELLIGENCE)

  set num_designs := Sys_Get_Player_Designs_Count(target_plr)

  // For human players, assign an AI design type to ensure accurate statistics
  if (not Sys_Are_We_Computer_Player(target_plr)) then
    for design_index := 1 to num_designs do
      set design_id := Sys_Get_Player_Design_ID(target_plr, design_index)
      set design_type := Sys_Get_Vehicle_Design_General_Type(target_plr, design_id)
      call Sys_Set_Vehicle_Design_Ai_Design_Type(target_plr, design_id, design_type)
    endfor
  endif

  // Compute design stats
  call Sys_Compute_AI_Design_Type_Statistics(target_plr)

  // Compute the total value of resources in ships and units
  // Run through a list of our designs
  if (num_designs > 0) then
    for design_index := 1 to num_designs do
      set design_id := Sys_Get_Player_Design_ID(target_plr, design_index)
      set design_type := Sys_Get_Vehicle_Design_General_Type(target_plr, design_id)
      set design_id := Sys_Get_Latest_Vehicle_Design_Of_AI_Type(target_plr, design_type)
      set is_ship := (Sys_Pos_String("Ship", design_type) > 0) or (Sys_Pos_String("Base", design_type) > 0)
      set is_unit := (not is_ship)
      // Don't count design types more than once even if we have multiple designs under a given design type
      if (lst_design_type_counted.indexof(design_type) <= 0) then
        call lst_design_type_counted.add(design_type)
        // The cost is of the latest design even if not all ships in the empire are updated
        set design_cost := Sys_Get_Vehicle_Design_Cost(design_id)
        set total_design_cost := design_cost.get(RESOURCE_TYPE_MINERALS) + design_cost.get(RESOURCE_TYPE_ORGANICS) + design_cost.get(RESOURCE_TYPE_RADIOACTIVES)
        // The design count is for the total number of ships/units with that type; Not just for that specific design
        set design_count := Sys_AI_Design_Type_Stats_Get_Vehicle_Count(design_type)
        if (is_ship) then
          set total_ship_cost := total_ship_cost + (total_design_cost * design_count)
        endif
        if (is_unit) then
          set total_unit_cost := total_unit_cost + (total_design_cost * design_count)
        endif
        // Temp debug output
        // call Sys_Debug_Print("Enemy Analysis", "      - Design = " + design_type + "; Count = " + Sys_Convert_Long_To_String(design_count))
      else
        // Since we are using only the latest design costs, hedge when we have multiple designs for a given design type
        if (is_ship) then
          set total_ship_cost_mod := total_ship_cost_mod - 0.01
        endif
        if (is_unit) then
          set total_ship_cost_mod := total_unit_cost_mod - 0.01
        endif
      endif
    endfor
  endif

  // Don't let our vehicle cost modifiers drop less than 90%
  set total_ship_cost_mod := Sys_Min_Real(total_ship_cost_mod, 0.9)
  set total_unit_cost_mod := Sys_Min_Real(total_unit_cost_mod, 0.9)

  // Temp debug output
  // call Sys_Debug_Print("Enemy Analysis", "      - Population score = " + Sys_Convert_Real_To_String(num_population * 10.0))
  // call Sys_Debug_Print("Enemy Analysis", "      - Facilities score = " + Sys_Convert_Real_To_String(num_facilities * 500.0))
  // call Sys_Debug_Print("Enemy Analysis", "      - Stored minerals score = " + Sys_Convert_Real_To_String(num_minerals * 0.625))
  // call Sys_Debug_Print("Enemy Analysis", "      - Stored organics score = " + Sys_Convert_Real_To_String(num_organics * 0.15625))
  // call Sys_Debug_Print("Enemy Analysis", "      - Stored radioactives score = " + Sys_Convert_Real_To_String(num_radioactives * 0.3125))
  // call Sys_Debug_Print("Enemy Analysis", "      - Minerals score = " + Sys_Convert_Real_To_String(num_minerals_produced * 5))
  // call Sys_Debug_Print("Enemy Analysis", "      - Organics score = " + Sys_Convert_Real_To_String(num_organics_produced * 1.25))
  // call Sys_Debug_Print("Enemy Analysis", "      - Radioactives score = " + Sys_Convert_Real_To_String(num_radioactives_produced * 2.5))
  // call Sys_Debug_Print("Enemy Analysis", "      - Research score = " + Sys_Convert_Real_To_String(num_research_pts * 2.0))
  // call Sys_Debug_Print("Enemy Analysis", "      - Tech Levels score = " + Sys_Convert_Real_To_String(num_tech_levels * (Sys_Divide_Long(num_tech_levels, 25) ^ 1.5)))
  // call Sys_Debug_Print("Enemy Analysis", "      - Intel score = " + Sys_Convert_Real_To_String(num_intel_pts * 1.0))
  // call Sys_Debug_Print("Enemy Analysis", "      - Ship cost score = " + Sys_Convert_Real_To_String(total_ship_cost * 1.0))
  // call Sys_Debug_Print("Enemy Analysis", "      - Unit cost score = " + Sys_Convert_Real_To_String(total_unit_cost * 0.5))

  // Calculate the score
  set player_score := player_score + (num_population * 10.0)
  set player_score := player_score + (num_facilities * 500.0)
  set player_score := player_score + (num_minerals * 0.625)
  set player_score := player_score + (num_organics * 0.15625)
  set player_score := player_score + (num_radioactives * 0.3125)
  set player_score := player_score + (num_minerals_produced * 5)
  set player_score := player_score + (num_organics_produced * 1.25)
  set player_score := player_score + (num_radioactives_produced * 2.5)
  set player_score := player_score + (num_research_pts * 2.0)
  set player_score := player_score + (num_tech_levels * (Sys_Divide_Long(num_tech_levels, 25) ^ 1.5))
  set player_score := player_score + (num_intel_pts * 1.0)
  set player_score := player_score + (total_ship_cost * 1.0 * total_ship_cost_mod)
  set player_score := player_score + (total_unit_cost * 0.5 * total_unit_cost_mod)

  return player_score
end

//------------------------------------------------------------------------
// Is_Empire_Friends_With_Enemies
//------------------------------------------------------------------------
function Is_Empire_Friends_With_Enemies returns boolean
params
  target_plr:                long
vars
  num_players:               long
  plr_index:                 long
  is_enemy:                  boolean
  is_known:                  boolean
  friends_with_enemy:        boolean := FALSE
begin

  // Get the number of Players
  set num_players := Sys_Get_Number_Of_Players()

  // Check to see if the target player is friends with any of our enemies
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      if (plr_index <> sys_long_Player_ID) and (plr_index <> target_plr) then
        set is_known := Sys_Empire_Politics_Is_Player_Known(sys_long_Player_ID, plr_index)
        set is_enemy := Sys_Empire_Politics_Is_Player_Enemy(sys_long_Player_ID, plr_index)
        // Friendly with enemy
        if (is_known) and (is_enemy) then
          if Sys_Empire_Politics_Is_Player_Ally(target_plr, plr_index) then
            set friends_with_enemy := TRUE
          endif
        endif
      endif
    endfor
  endif

  return friends_with_enemy
end

//------------------------------------------------------------------------
// Are_Our_Friends_Enemies_Of_Another_Friend
//------------------------------------------------------------------------
function Are_Our_Friends_Enemies_Of_Another_Friend returns boolean
params
  target_plr:                long
vars
  num_players:               long
  plr_index:                 long
  is_friend:                 boolean
  is_known:                  boolean
  enemy_of_friends:          boolean := FALSE
begin

  // Get the number of Players
  set num_players := Sys_Get_Number_Of_Players()

  // Check to see if the target player is friends with any of our enemies
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      if (plr_index <> sys_long_Player_ID) and (plr_index <> target_plr) then
        set is_known := Sys_Empire_Politics_Is_Player_Known(sys_long_Player_ID, plr_index)
        set is_friend := Sys_Empire_Politics_Is_Player_Ally(sys_long_Player_ID, plr_index)
        // Is the target player an enemy of one of our other friends?
        if (is_known) and (is_friend) then
          if Sys_Empire_Politics_Is_Player_Enemy(target_plr, plr_index) then
            set enemy_of_friends := TRUE
          endif
        endif
      endif
    endfor
  endif

  return enemy_of_friends
end

//------------------------------------------------------------------------
// Compatible_AI_Categorization
//------------------------------------------------------------------------
function Compatible_AI_Categorization returns long
params
  target_plr:                long
vars
  their_ai_categorization:   long
  compatibility_score:       long
begin

  // Get our government type to the other player's government type
  set their_ai_categorization := Sys_Get_AI_Storage_Long(target_plr, 1, 11)

  // Compare our government types to generate a score
  If (lng_AI_Categorization > their_ai_categorization) then
    set compatibility_score := lng_AI_Categorization - their_ai_categorization
  else
    set compatibility_score := their_ai_categorization - lng_AI_Categorization
  endif

  // Add 1 if the player is a human player
  If (not Sys_Are_We_Computer_Player(target_plr)) then
    set compatibility_score := 1
  endif

  return compatibility_score
end

//------------------------------------------------------------------------
// Compatible_Government_Types
//------------------------------------------------------------------------
function Compatible_Government_Types returns long
params
  target_plr:                long
vars
  our_govt_id:               long
  their_govt_id:             long
  compatibility_score:       long
begin

  // Get our government type to the other player's government type
  set our_govt_id := Get_Government_Type_Id(sys_long_Player_ID)
  set their_govt_id := Get_Government_Type_Id(target_plr)

  // Compare our government types to generate a score
  If (our_govt_id > their_govt_id) then
    set compatibility_score := Sys_Trunc((our_govt_id - their_govt_id) / 2)
  else
    set compatibility_score := Sys_Trunc((their_govt_id - our_govt_id) / 2)
  endif

  return compatibility_score
end

//------------------------------------------------------------------------
// Compatible_Society_Types
//------------------------------------------------------------------------
function Compatible_Society_Types returns long
params
  target_plr:                long
vars
  our_society_id:            long
  their_society_id:          long
  compatibility_score:       long
begin

  // Get our society type to the other player's government type
  set our_society_id := Get_Society_Type_Id(sys_long_Player_ID)
  set their_society_id := Get_Society_Type_Id(target_plr)

  // Compare our society types to generate a score
  If (our_society_id > their_society_id) then
    set compatibility_score := Sys_Trunc((our_society_id - their_society_id) / 2)
  else
    set compatibility_score := Sys_Trunc((their_society_id - our_society_id) / 2)
  endif

  return compatibility_score
end

//------------------------------------------------------------------------
// Compare_Score
//------------------------------------------------------------------------
function Compare_Score returns boolean
params
vars
  index:                     long
  num_players:               long
  num_alliances:             long
  our_alliance_id:           long
  our_score:                 real
  their_score:               real
  pct_compare:               long
  score_note:                string
begin

  // Get the number of Players
  set num_players := Sys_Get_Number_Of_Players()

  // Are we in an Alliance?
  set our_alliance_id := Sys_Empire_Politics_In_Alliance_ID(sys_long_Player_ID)

  // Get our score
  if (our_alliance_id > 0) then
    // If we are in an alliance, use our alliance score for comparison
    set our_score := Sys_AI_Empire_Stats_Get_Alliance_Score(our_alliance_id)
  else
    // If we are not in an alliance, use our score for comparison
    set our_score := Sys_AI_Empire_Stats_Get_Empire_Score(sys_long_Player_ID)
  endif

  // Save our score to memory
  call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 1, 1, Sys_Trunc(our_score))

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "---------------------")
  call Sys_Debug_Print("Enemy Analysis", "  - Score Comparison:")

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "    - Our score = " + Sys_Convert_Real_To_String(our_score))

  // Compare our score towards the score of each player
  if (num_players > 0) then
    for index := 1 to num_players do
      set pct_compare := 0
      // Get their score
      if (index <> sys_long_Player_ID) then
        set their_score := Sys_AI_Empire_Stats_Get_Empire_Score(index)
        set score_note := " (Sys Score Fx)"
        // If their score is reported as 0, then check memory (for other computer players) or estimate it...
        if (their_score <= 0) then
          if Sys_Are_We_Computer_Player(index) then
            // Try to get their score from memory
            set their_score := Sys_Get_AI_Storage_Long(index, 1, 1) * 1.0
            // If there score is still 0, then estimate it
            if (their_score <= 0) then
              set their_score := Estimate_Player_Score(index)
              set score_note := " (Estimate!)"
            else
              set score_note := " (Memory!)"
            endif
          else
            if (their_score <= 0) then
              set their_score := Estimate_Player_Score(index)
              set score_note := " (Estimate!)"
            endif
          endif
        endif
        // Calculate the percent difference
        set pct_compare := Sys_Trunc((their_score / our_score) * 100)
        // Determine where we rank in score
        if (our_score < their_score) then
          set lng_Politics_Score_Rank := lng_Politics_Score_Rank + 1
        endif
        // Debug Output
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Empire_Get_Empire_Name(index) + " Score = " + Sys_Convert_Real_To_String(their_score) + score_note)
        call Sys_Debug_Print("Enemy Analysis", "      - Relative Score = " + Sys_Convert_Long_To_String(pct_compare) + "%")
      endif
      call lst_Politics_Score_Versus_Player.add(pct_compare)
    endfor
  endif

  // Get the number of alliances
  set num_alliances := Sys_Get_Number_Of_Alliances()

  // Compare our score towards the score of each Alliance
  if (num_alliances > 0) then
    for index := 1 to num_alliances do
      set pct_compare := 0
      if (index <> our_alliance_id) then
        set their_score := Sys_AI_Empire_Stats_Get_Alliance_Score(index)
        set pct_compare := Sys_Trunc((their_score / our_score) * 100)
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Alliance_Get_Alliance_Name(index) + " = " + Sys_Convert_Long_To_String(pct_compare) + "%")
      endif
      call lst_Politics_Score_Versus_Alliance.add(pct_compare)
    endfor
  endif

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "    - Estimated score rank = " + Sys_Convert_Long_To_String(lng_Politics_Score_Rank))

  set lng_AI_Empire_Score := Sys_Trunc(our_score)
  set lng_AI_Empire_Score_Rank := lng_Politics_Score_Rank

  return TRUE
end

//------------------------------------------------------------------------
// Compute_Fear
//------------------------------------------------------------------------
function Compute_Fear returns boolean
params
vars
  index:                     long
  num_players:               long
  num_alliances:             long
  fear_pts:                  long
  fear_mod:                  long
  fear_reducer:              real := 1.0
  pct_compare:               long
  avg_sys_dist:              long
  friendship_pts:            long
  our_alliance_id:           long
begin

  // Get the number of Players
  set num_players := Sys_Get_Number_Of_Players()

  // Load our political modifiers
  call AI_Set_Political_Treaty_Elements()

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "-------------------------------")
  call Sys_Debug_Print("Enemy Analysis", "  - Fear and Friendship Points:")

  // If we still have an early game score, don't take results too seriously
  if (lng_AI_Empire_Score < 300000) then
    set fear_reducer := (lng_AI_Empire_Score / 300000)
  endif

  // Determine our fear level towards each player
  // Positive fear is true fear; negative fear is confidence
  if (num_players > 0) then
    for index := 1 to num_players do
      set fear_pts := 0
      set friendship_pts := 0
      set pct_compare := lst_Politics_Score_Versus_Player.get(index)
      set avg_sys_dist := lst_Politics_Player_Avg_Sys_Dist.get(index)
      // Modify fear by distance
      set fear_mod := Sys_Max_Long(10, 20 - avg_sys_dist)

      if (index <> sys_long_Player_ID) and Sys_Empire_Politics_Is_Player_Known(sys_long_Player_ID, index) and (pct_compare > 0) then
        set fear_pts := Sys_Trunc(Sys_Ln(pct_compare / 100) * fear_mod)
        set friendship_pts := Get_Treaty_Friendship_Value(index)
        // Reduce fear based if it's an early game where relatively scores can fluctuate easily
        set fear_pts := Sys_Trunc(fear_pts * fear_reducer)
        // Adjust our fear level based on our AI category
        if Sys_Are_We_Neutral_Empire(index) then
          set fear_pts := Sys_Divide_Long(fear_pts, 2)
        endif
        // Add a random factor
        if (fear_pts <> 0) then
          case lng_AI_Categorization
            AI_CATEGORY_PEACEFUL:
              set fear_pts := fear_pts + Sys_Get_Random_Long(0, 4)
            AI_CATEGORY_NEUTRAL:
              set fear_pts := fear_pts + Sys_Get_Random_Long(-2, 2)
            AI_CATEGORY_AGGRESSIVE:
              set fear_pts := fear_pts - Sys_Get_Random_Long(0, 4)
            AI_CATEGORY_XENOPHOBIC:
              set fear_pts := fear_pts - Sys_Get_Random_Long(2, 4)
          endcase
        endif
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Empire_Get_Empire_Name(index))
        call Sys_Debug_Print("Enemy Analysis", "      - Fear Points = " + Sys_Convert_Long_To_String(fear_pts))
        call Sys_Debug_Print("Enemy Analysis", "      - Friendship Points = " + Sys_Convert_Long_To_String(friendship_pts))
      endif
      // Update our fear and friendship points for Empires
      call lst_Politics_Fear_Towards_Player.add(fear_pts)
      call lst_Politics_Friendship_Towards_Player.add(friendship_pts)
    endfor
  endif

  // Get the number of alliances
  set num_alliances := Sys_Get_Number_Of_Alliances()

  // Are we in an Alliance?
  set our_alliance_id := Sys_Empire_Politics_In_Alliance_ID(sys_long_Player_ID)

  // Determine our fear level towards each Alliance
  // Positive fear is true fear; negative fear is confidence
  if (num_alliances > 0) then
    for index := 1 to num_alliances do
      set fear_pts := 0
      set pct_compare := lst_Politics_Score_Versus_Alliance.get(index)

      if (index <> our_alliance_id) and (pct_compare > 0) then
        set fear_pts := Sys_Trunc(Sys_Ln(pct_compare / 100) * 15)
        // Adjust our fear level based on our AI category
        if (fear_pts <> 0) then
          case lng_AI_Categorization
            AI_CATEGORY_PEACEFUL:
              set fear_pts := fear_pts + Sys_Get_Random_Long(0, 4)
            AI_CATEGORY_NEUTRAL:
              set fear_pts := fear_pts + Sys_Get_Random_Long(-2, 2)
            AI_CATEGORY_AGGRESSIVE:
              set fear_pts := fear_pts - Sys_Get_Random_Long(0, 4)
            AI_CATEGORY_XENOPHOBIC:
              set fear_pts := fear_pts - Sys_Get_Random_Long(2, 4)
          endcase
        endif
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Alliance_Get_Alliance_Name(index))
        call Sys_Debug_Print("Enemy Analysis", "      - Fear Points = " + Sys_Convert_Long_To_String(fear_pts))
      endif
      // Update our fear points for Alliances
      call lst_Politics_Fear_Towards_Alliance.add(fear_pts)
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Compute_Target_Priorities
//------------------------------------------------------------------------
function Compute_Target_Priorities returns boolean
params
vars
  list_count:                     long
  list_index:                     long
  fear_towards_plr:               long
  pct_compare:                    long
  our_alliance_id:                long
  their_alliance_id:              long
  our_home_sys:                   long
  avg_sys_dist:                   long
  pct_shared_sys:                 long
  our_govt_type:                  string
  their_govt_type:                string
  our_society_type:               string
  their_society_type:             string
  our_atmosphere_type:            long
  their_atmosphere_type:          long
  our_colonization_ability:       long
  their_colonization_ability:     long
  atmosphere_mod:                 long := 0
  colonization_mod:               long := 0
  proximity_mod:                  long := 0
  shared_mod:                     long := 0
  team_mod:                       long := 0
  evil_mod:                       long := 0
  target_pts:                     long
  friendship_pts:                 long
  strategy_pts:                   long
  combat_pts:                     long
  pol_status:                     long
  ai_categorization_sim_score:    long
  government_sim_score:           long
  society_sim_score:              long
  their_primary_enemy:            long
  their_primary_friend:           long
  max_pts:                        long := -99
  max_weak_pts:                   long := -99
  priority_plr:                   long
  debug_note:                     string := ""
begin

  // Get our Empire's details
  set our_alliance_id := Sys_Empire_Politics_In_Alliance_ID(sys_long_Player_ID)
  set our_home_sys := Sys_Get_Empire_Home_System(sys_long_Player_ID)
  set our_atmosphere_type := lst_Politics_Player_Native_Atmosphere.get(sys_long_Player_ID)
  set our_colonization_ability := lst_Politics_Player_Colonization_Ability.get(sys_long_Player_ID)

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "----------------------------------------")
  call Sys_Debug_Print("Enemy Analysis", "  - Target Priority and Strategy Points:")

  // Get the number of players
  set list_count := lst_Politics_Fear_Towards_Player.count()

  // Determine our target priority levels versus other players
  if (list_count > 0) then
    for list_index := 1 to list_count do
      // Reset variables
      set target_pts := 0
      set strategy_pts := 0
      set atmosphere_mod := 0
      set colonization_mod := 0
      set proximity_mod := 0
      set shared_mod := 0
      set evil_mod := 0
      set team_mod := 0
      set debug_note := " (Not Known)"
      // Collect data on the target player
      if (sys_long_Player_ID <> list_index) and Sys_Empire_Politics_Is_Player_Known(sys_long_Player_ID, list_index) then
        set pol_status := Sys_Empire_Politics_Get_Status_With_Player(sys_long_Player_ID, list_index)
        set ai_categorization_sim_score := Compatible_AI_Categorization(list_index)
        set government_sim_score := Compatible_Government_Types(list_index)
        set society_sim_score := Compatible_Society_Types(list_index)
        set fear_towards_plr := lst_Politics_Fear_Towards_Player.get(list_index)
        set friendship_pts := lst_Politics_Friendship_Towards_Player.get(list_index)
        set combat_pts := lst_Space_Combat_Pts_vs_Player.get(list_index) + lst_Ground_Combat_Pts_vs_Player.get(list_index)
        set avg_sys_dist := lst_Politics_Player_Avg_Sys_Dist.get(list_index)
        set pct_shared_sys := lst_Politics_Player_Overlap_Pct.get(list_index)
        set their_atmosphere_type := lst_Politics_Player_Native_Atmosphere.get(list_index)
        set their_colonization_ability := lst_Politics_Player_Colonization_Ability.get(list_index)
        set their_primary_enemy := Sys_Get_AI_Storage_Long(list_index, 1, 3)
        set their_primary_friend := Sys_Get_AI_Storage_Long(list_index, 1, 4)
        set debug_note := " (Known)"

        // Set our shared system modifier
        if (pct_shared_sys > 33) then
          set shared_mod := 2
        else
          if (pct_shared_sys > 10) then
            set shared_mod := 1
          endif
        endif

        // Adjust modifiers for quadrant density
        // Proximity in high density quadrants
        if (bool_Quadrant_Density_High) then
          // Average distance is less than half the high density threshold
          if (avg_sys_dist <= Sys_Divide_Long(QUADRANT_SYS_DENSITY_HIGH, 2)) then
            set proximity_mod := 3
          else
            // Average distance is less than or equal to the high density threshold
            if (avg_sys_dist <= QUADRANT_SYS_DENSITY_HIGH) then
              set proximity_mod := 2
            else
              // Average distance is more than the high density threshold
              if (avg_sys_dist > QUADRANT_SYS_DENSITY_HIGH) then
                set proximity_mod := 1
              endif
            endif
          endif
        endif
        // Proximity in medium density quadrants
        if (bool_Quadrant_Density_Medium) then
          // Average distance is less than half the medium density threshold
          if ((avg_sys_dist <= Sys_Divide_Long(QUADRANT_SYS_DENSITY_MEDIUM, 2))) then
            set proximity_mod := 2
          else
            // Average distance is less than or equal to the medium density threshold
            if (avg_sys_dist <= QUADRANT_SYS_DENSITY_MEDIUM) then
              set proximity_mod := 1
            else
              // Average distance is more than the medium density threshold
              if (avg_sys_dist > QUADRANT_SYS_DENSITY_MEDIUM) then
                set proximity_mod := -1
              endif
            endif
          endif
        endif
        // Proximity in low density quadrants
        // Average distance is less than half the low density threshold
        if ((avg_sys_dist <= Sys_Divide_Long(QUADRANT_SYS_DENSITY_LOW, 2))) then
          set proximity_mod := 2
        else
          // Average distance is less than or equal to the low density threshold
          if (avg_sys_dist <= QUADRANT_SYS_DENSITY_LOW) then
            set proximity_mod := 0
          else
            // Average distance is more than twice the low density threshold
            if (avg_sys_dist > QUADRANT_SYS_DENSITY_LOW) then
              set proximity_mod := -2
            endif
          endif
        endif

        // Set atmosphere type modifier
        if (our_atmosphere_type = their_atmosphere_type) then
          set atmosphere_mod := (2 * proximity_mod) + shared_mod
        else
          set atmosphere_mod := -1
        endif
        // Set colonization ability modifier
        if (our_colonization_ability <= their_colonization_ability) then
          set colonization_mod := (2 * proximity_mod) + shared_mod
        else
          set colonization_mod := (1 * proximity_mod) - 1
        endif

        // Add target priority for quadrant and colonization checks
        set target_pts := target_pts + atmosphere_mod + colonization_mod

        // Add target priority for other players' AI category, government and society type similarity
        set target_pts := target_pts + ai_categorization_sim_score + government_sim_score + society_sim_score

        // Add target priority for players depending on our political status
        case pol_status
          POLITICAL_STATUS_TYPE_WAR:
            // Add less priority points for wars with neutral players
            if Sys_Are_We_Neutral_Empire(list_Index) then
              set target_pts := target_pts + 1
              // Track the number of our Neutral player wars
              set lng_AI_Num_Of_Neutral_Wars := lng_AI_Num_Of_Neutral_Wars + 1
              set lng_AI_Num_Of_Enemies := lng_AI_Num_Of_Enemies + 1
            else
              // Add more priority points for human players and full AI empires
              if Sys_Are_We_Computer_Player(list_index) then
                set target_pts := target_pts + 3
              else
                set target_pts := target_pts + 5
              endif
              // Track the number of our wars
              set lng_AI_Num_Of_Wars := lng_AI_Num_Of_Wars + 1
              set lng_AI_Num_Of_Enemies := lng_AI_Num_Of_Enemies + 1
            endif
          POLITICAL_STATUS_TYPE_TREATY:
            if (friendship_pts >= 10) then
              set target_pts := target_pts - 3
              // Track the number of our friendly treaties
              set lng_AI_Num_Of_Friendly_Treaties := lng_AI_Num_Of_Friendly_Treaties + 1
            else
              if (friendship_pts >= 5) then
                set target_pts := target_pts - 1
              else
                set target_Pts := target_pts + 1
              endif
              // Track the number of our other treaties
              set lng_AI_Num_Of_Other_Treaties := lng_AI_Num_Of_Other_Treaties + 1
            endif
          POLITICAL_STATUS_TYPE_KNOWN:
            set target_pts := target_pts + 2
            // Count the number of known, but no treaty players
            set lng_AI_Num_Of_Known_Players := lng_AI_Num_Of_Known_Players + 1
            set lng_AI_Num_Of_Enemies := lng_AI_Num_Of_Enemies + 1
        endcase

        // Add target priority for human players
        if (not Sys_Are_We_Computer_Player(list_index)) then
          set target_pts := target_pts + 1 + colonization_mod
          // Note if our game has stronger empires run by human players
          if (fear_towards_plr > 5) then
            set target_pts := target_pts + 1 + colonization_mod
            set bool_Human_Empire_Is_Strong := TRUE
          endif
        endif

        // Add target priority for the mega evil player
        if (lng_Politics_Mega_Evil_Player = list_index) then
          set evil_mod := 10 + (proximity_mod * 3)
          set target_pts := target_pts + evil_mod
        endif
        
        // Reduce target priority for players on our team
        if bool_AI_Team_Mode_On then
          if Sys_Are_We_Computer_Player(list_index) then
            set team_mod := 10
            set target_pts := target_pts - team_mod
          endif
        endif

        // Add target priority for players that are either increasingly weaker or stronger than our empire
        if (fear_towards_plr > 20)  or (fear_towards_plr < -20) then
          set target_pts := target_pts + 3
        else
          if (fear_towards_plr > 10) or (fear_towards_plr < -10) then
            set target_pts := target_pts + 2
          else
            if (fear_towards_plr > 5)  or (fear_towards_plr < -5) then
              set target_pts := target_pts + 1
            endif
          endif
        endif

        // Add target priority for the player most actively fighting us
        if (list_index = lng_Combat_Primary_Enemy) then
          set target_pts := target_pts + 10
        endif

        // Add target priority points for players we've had combats with in the last 25 turns
        if (combat_pts < -20) or (combat_pts > 20) then
          set target_pts := target_pts + 3
        else
          if (combat_pts < -10) or (combat_pts > 10) then
            set target_pts := target_pts + 2
          else
            if (combat_pts < 0) or (combat_Pts > 0) then
              set target_pts := target_pts + 1
            endif
          endif
        endif

        // Add target priority based on empire strategy
        // Target weaker empires if our strategy is to attack weak players
        if (lng_AI_Empire_Strategy = AI_EMPIRE_STRATEGY_WEAK_ATTACK) then
          if (fear_towards_plr < -10) then
            set target_pts := target_pts + 2
          endif
        endif
        // Target human empires if our strategy is to attack human players
        if (lng_AI_Empire_Strategy = AI_EMPIRE_STRATEGY_HUMAN_ATTACK) then
          if (not Sys_Are_We_Computer_Player(list_index)) then
            set target_pts := target_pts + 2
          endif
        endif

        // Add target priority for players that are friends with our enemies
        if Is_Empire_Friends_With_Enemies(list_index) then
          set target_pts := target_pts + 1
          set debug_note := " (Known; Friends with Enemies)"
        else
          set target_pts := target_pts - 1
        endif
      endif

      // Set our target priority level for the selected player
      if (target_pts < 5) then
        call lst_Politics_Target_Player_Priority.add(TARGET_PRIORITY_LOW)
      else
        if (target_pts >= 5) and (target_pts <= 10) then
          call lst_Politics_Target_Player_Priority.add(TARGET_PRIORITY_MEDIUM)
        else    
          call lst_Politics_Target_Player_Priority.add(TARGET_PRIORITY_HIGH)
        endif
      endif

      // Track the number of priority enemies we have
      if (target_pts > 10) then
        set lng_AI_Num_Of_Priority_Enemies := lng_AI_Num_Of_Priority_Enemies + 1
      endif

      // Note our primary enemy
      if (target_pts >= max_pts) and (sys_long_Player_ID <> list_index) then
        // If target priority equivalent, use fear as tiebreaker
        if (target_pts = max_pts) then
          if (lst_Politics_Fear_Towards_Player.get(list_index) > lst_Politics_Fear_Towards_Player.get(lng_Politics_Primary_Enemy)) then
            set lng_Politics_Primary_Enemy := list_index
            set max_pts := target_pts
          endif
        else
          set lng_Politics_Primary_Enemy := list_index
          set max_pts := target_pts
        endif
      endif

      // Note our primary target that is weaker than our empire
      if (target_pts >= max_weak_pts) and (sys_long_Player_ID <> list_index) then
        if (fear_towards_plr < -5) then
          set lng_Politics_Primary_Weak_Enemy := list_index
          set max_weak_pts := target_pts
        endif
      endif

      // Strategic Considerations
      set strategy_pts := 10
      // Consider more favorably if we are not competing for the same quadrant resources
      if (bool_Quadrant_Density_High) then
        set strategy_pts := strategy_pts - atmosphere_mod - colonization_mod - proximity_mod - shared_mod + team_mod - evil_mod
        // Adjust for player similarity (extra emphasis)
        set strategy_pts := strategy_pts - ((ai_categorization_sim_score + government_sim_score + society_sim_score) * 2)
      else
        if (bool_Quadrant_Density_Medium) then
          set strategy_pts := strategy_pts - atmosphere_mod - colonization_mod - proximity_mod - shared_mod + team_mod - evil_mod
          // Adjust for player similarity (standard emphasis)
          set strategy_pts := strategy_pts - (ai_categorization_sim_score + government_sim_score + society_sim_score)
        else
          if (bool_Quadrant_Density_Low) then
            set strategy_pts := strategy_pts - atmosphere_mod - colonization_mod - proximity_mod - shared_mod + team_mod - evil_mod
            // Adjust for player similarity (less emphasis)
            set strategy_pts := strategy_pts - Sys_Trunc((ai_categorization_sim_score + government_sim_score + society_sim_score) / 2)
          endif
        endif
      endif
      // Save strategy points
      call lst_Politics_Strategy_Towards_Player.add(strategy_pts)

      // Debug output
      if (list_index <> sys_long_Player_ID) then
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Empire_Get_Empire_Name(list_index) + debug_note)
        call Sys_Debug_Print("Enemy Analysis", "      - Target Priority Pts = " + Sys_Convert_Long_To_String(target_pts))
        call Sys_Debug_Print("Enemy Analysis", "      - Strategy Pts = " + Sys_Convert_Long_To_String(strategy_pts))
        call Sys_Debug_Print("Enemy Analysis", "        - Shared mod = " + Sys_Convert_Long_To_String(shared_mod))
        call Sys_Debug_Print("Enemy Analysis", "        - Proximity mod = " + Sys_Convert_Long_To_String(proximity_mod))
        call Sys_Debug_Print("Enemy Analysis", "        - Atmosphere mod = " + Sys_Convert_Long_To_String(atmosphere_mod))
        call Sys_Debug_Print("Enemy Analysis", "        - Colonization mod = " + Sys_Convert_Long_To_String(colonization_mod))
        call Sys_Debug_Print("Enemy Analysis", "        - AI Category score = " + Sys_Convert_Long_To_String(ai_categorization_sim_score))
        call Sys_Debug_Print("Enemy Analysis", "        - Government score = " + Sys_Convert_Long_To_String(government_sim_score))
        call Sys_Debug_Print("Enemy Analysis", "        - Society score = " + Sys_Convert_Long_To_String(society_sim_score))
        call Sys_Debug_Print("Enemy Analysis", "        - Mega Evil mod = " + Sys_Convert_Long_To_String(evil_mod))
        call Sys_Debug_Print("Enemy Analysis", "        - Team mod = " + Sys_Convert_Long_To_String(team_mod))
      endif
    endfor
    // Debug output
    if (lng_Politics_Primary_Enemy > 0) then
      call Sys_Debug_Print("Enemy Analysis", "  - Primary Enemy = " + Sys_Empire_Get_Empire_Name(lng_Politics_Primary_Enemy))
    else
      call Sys_Debug_Print("Enemy Analysis", "  - No Primary Enemy")
    endif
    if (lng_Politics_Primary_Weak_Enemy > 0) then
      call Sys_Debug_Print("Enemy Analysis", "  - Primary Weak Enemy = " + Sys_Empire_Get_Empire_Name(lng_Politics_Primary_Weak_Enemy))
    else
      call Sys_Debug_Print("Enemy Analysis", "  - No Primary Weak Enemy")
    endif
    call Sys_Debug_Print("Enemy Analysis", "  - # Priority Enemies = " + Sys_Convert_Long_To_String(lng_AI_Num_Of_Priority_Enemies))
  endif

  // Get the number of alliances we are not involved in
  set list_count := lst_Politics_Fear_Towards_Alliance.count()

  // Determine our target priorities versus alliances
  if (list_count > 0) then
    for list_index := 1 to list_count do
      set target_pts := 0
      if (our_alliance_id <> list_index) then
        set pol_status := Sys_Empire_Politics_Get_Status_With_Alliance(sys_long_Player_ID, list_index)
        set fear_towards_plr := lst_Politics_Fear_Towards_Alliance.get(list_index)

        // Add target priority for players depending on our political status
        case pol_status
          POLITICAL_STATUS_TYPE_WAR:
            set target_pts := target_pts + 2
          POLITICAL_STATUS_TYPE_TREATY:
            set target_pts := target_pts - 1
          POLITICAL_STATUS_TYPE_KNOWN:
            set target_pts := target_pts + 1
        endcase

        // Add target priority for players that are either significantly weaker or stronger than our empire
        if (fear_towards_plr > 10) then
          set target_pts := target_pts + 2
        endif
        if (fear_towards_plr < -10) then
          set target_pts := target_pts + 1
        endif
      endif

      // Set our target priority for the selected alliance
      if (target_pts <= 3) then
        call lst_Politics_Target_Alliance_Priority.add(TARGET_PRIORITY_LOW)
      endif
      if (target_pts > 3) and (target_pts <= 6) then
        call lst_Politics_Target_Alliance_Priority.add(TARGET_PRIORITY_MEDIUM)
      endif
      if (target_pts > 6) then
        call lst_Politics_Target_Alliance_Priority.add(TARGET_PRIORITY_HIGH)
      endif

      // Debug Output
      if (list_index <> our_alliance_ID) then
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Alliance_Get_Alliance_Name(list_index) + " = " + Sys_Convert_Long_To_String(target_pts))
      endif
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Compute_State_Modifier
//------------------------------------------------------------------------
function Compute_State_Modifier returns boolean
vars
  list_count:                long
  list_index:                long
  plr_count:                 long
  plr_index:                 long
  plr_score:                 long
  lst_plr_score:             longlist
  total_score:               long
  avg_score:                 long
  alliance_id:               long
  friendship_pts:            long
  strategic_pts:             long
begin

  // Get the number of players
  set plr_count := Sys_Get_Number_Of_Players()

  // Determine our state modifier by the sum of our fears towards the other players
  set list_count := lst_Politics_Fear_Towards_Player.count()

  if (list_count > 0) then
    for list_index := 1 to list_count do
      set lng_Politics_State_Modifier := lng_Politics_State_Modifier + lst_Politics_Fear_Towards_Player.get(list_index)
    endfor
  endif

  // Alternative using top 25%
  for plr_index := 1 to plr_count do
    set plr_score := Sys_trunc(Sys_AI_Empire_Stats_Get_Empire_Score(plr_index))
    // Add score
    call lst_plr_score.add(plr_score)
  endfor

  // Prepare for sort
  call Sys_Prepare_For_List_Sort()
  call Sys_Set_List_Sort_Field(1, lst_plr_score)
  call Sys_Add_List_Sort_Sort_Column(1, FALSE)
  call Sys_Execute_List_Sort()

  // Take the top 25% of scores to average
  set plr_count := Sys_Divide_Long(plr_index, 4)

  for plr_index := 1 to plr_count do
    set total_score := total_score + lst_plr_score.get(plr_index)
  endfor

  // Note the average score of the top 25%
  set avg_score := Sys_Divide_Long(avg_score, 4)

  // Our final state modifier is the sum of our fear levels divided by the number of other empires
  if (plr_count > 1) then
    set lng_Politics_State_Modifier := Sys_Divide_Long(lng_Politics_State_Modifier, plr_count - 1)
  endif

  set lng_AI_Empire_State_Modifier := lng_Politics_State_Modifier

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "  - Empire State Modifier = " + Sys_Convert_Long_To_String(lng_Politics_State_Modifier))

  // Note our overall performance level
  if (lng_Politics_State_Modifier < -20) then
    set lng_AI_Empire_Overall_Performance := AI_EMPIRE_OVERALL_EXCELLENT
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    - Overall Performance = Excellent")
  else
    if (lng_Politics_State_Modifier >= -20) and (lng_Politics_State_Modifier < -5) then
      set lng_AI_Empire_Overall_Performance := AI_EMPIRE_OVERALL_GOOD
      // Debug output
      call Sys_Debug_Print("Enemy Analysis", "    - Overall Performance = Good")
    else
      if (lng_Politics_State_Modifier >= -5) and (lng_Politics_State_Modifier < 5) then
        set lng_AI_Empire_Overall_Performance := AI_EMPIRE_OVERALL_OK
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - Overall Performance = Ok")
      else
        if (lng_Politics_State_Modifier >= 5) and (lng_Politics_State_Modifier < 20) then
          set lng_AI_Empire_Overall_Performance := AI_EMPIRE_OVERALL_POOR
          // Debug output
          call Sys_Debug_Print("Enemy Analysis", "    - Overall Performance = Poor")
        else
          set lng_AI_Empire_Overall_Performance := AI_EMPIRE_OVERALL_TERRIBLE
          // Debug output
          call Sys_Debug_Print("Enemy Analysis", "    - Overall Performance = Terrible")
        endif
      endif
    endif
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Compute_Cooperation_Level (WIP)
//------------------------------------------------------------------------
function Compute_Cooperation_Level returns boolean
vars
  num_players:               long
  plr_index:                 long
  strategy_pts:              long
  friendship_pts:            long
  coop_level:                long
  coop_resource:             long
  coop_tech:                 long
  coop_enemy_target:         long
  coop_enemy_target_name:    string
  coop_spec_req:             long
  needed_resource:           string
  needed_tech:               string
  special_req:               string
  base_index:                long
begin

  // Get the number of players
  set num_players := Sys_Get_Number_Of_Players()

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "-----------------------")
  call Sys_Debug_Print("Enemy Analysis", "  - Cooperation Status:")

  // Determine our target priority levels versus other players
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      // Reset variables
      set coop_level := 0
      set coop_resource := 0
      set coop_tech := 0
      set coop_enemy_target := 0
      set coop_spec_req := 0
      set needed_resource := ""
      set needed_tech := ""
      set special_req := ""
      // Based on our strategic assessment and current level of friendship, determine our level of cooperation
      if (plr_index <> sys_long_Player_ID) and Sys_Empire_Politics_Is_Player_Known(plr_index, sys_long_Player_ID) then
        // Get our strategy points and friendship points for the selected player
        set strategy_pts := lst_Politics_Strategy_Towards_Player.get(plr_index)
        set friendship_pts := lst_Politics_Friendship_Towards_Player.get(plr_index)
        // If we have good strategic incentive, take an optimistic approach to cooperation
        if (strategy_pts > 5) then
          if (friendship_pts > 15) then
            set coop_level := COOP_LEVEL_PARTNER
          else
            if (friendship_pts > 9) then
              // Continue growing our cooperation level
              set coop_level := COOP_LEVEL_HIGH
            else
              if (friendship_pts > 3) then
                // Continue growing our cooperation level
                set coop_level := COOP_LEVEL_MEDIUM
              else
                // Consider improving cooperation in the future even if things aren't so great now
                set coop_level := COOP_LEVEL_LOW
              endif
            endif
          endif
        else
          // If we have moderate strategic incentive and good relations, set our cooperation level to medium
          if (strategy_pts > 0) then
            if (friendship_pts > 0) then
              // Encourage more future cooperation
              set coop_level := COOP_LEVEL_MEDIUM
            else
              // Consider only most basic cooperation level to start
              set coop_level := COOP_LEVEL_LOW
            endif
          else
            // Strategy points <= 0
            // Consider only the most basic cooperation level
            set coop_level := COOP_LEVEL_BASIC
          endif
        endif

        // If this an AI team game then at least cooperate at a medium level
        if Sys_Empire_Politics_Is_Player_On_Our_Team(sys_long_Player_ID, plr_index) then
          set coop_level := Sys_Max_Long(coop_level, COOP_LEVEL_MEDIUM)
        endif

        // Note our other cooperation needs
        // Resources
        if (bool_Race_Minerals_Low) and (bool_Race_Organics_Low) and (bool_Race_Radioactives_Low) then
          set coop_resource := COOP_RESOURCES_ALL
          set needed_resource := "All"
        else
          if (bool_Race_Minerals_Low) then
            set coop_resource := COOP_RESOURCES_MINERALS
            set needed_resource := "Minerals"
          else
            if (bool_Race_Radioactives_Low) then
              set coop_resource := COOP_RESOURCES_RADIOACTIVES
              set needed_resource := "Radioactives"
            else
              if (bool_Race_Organics_Low) then
                set coop_resource := COOP_RESOURCES_ORGANICS
                set needed_resource := "Organics"
              else
                set needed_resource := "None"
              endif
            endif
          endif
        endif
        // Technology
        // Colonization technology
        if (lst_Politics_Player_Colonization_Ability.get(sys_long_Player_ID) < lst_Politics_Player_Colonization_Ability.get(plr_index)) then
          set coop_tech := COOP_TECH_COLONIZATION
          set needed_tech := "Colonization"
        else
          // Engine technology
          if (bool_Enemy_Ships_Are_Faster) or (bool_Enemy_Ships_Are_Much_Faster) then
            set coop_tech := COOP_TECH_ENGINES
            set needed_tech := "Engines"
          else
            // Ship technology
            if (bool_Enemy_Ahead_In_Ships) or (bool_Enemy_Far_Ahead_In_Ships)  then
              set coop_tech := COOP_TECH_SHIPS
              set needed_tech := "Ships"
            else
              // Unit technology
              if (bool_Race_Losing_Colonies_In_Combat) then
                set coop_tech := COOP_TECH_UNITS
                set needed_tech := "Units"
              else
                // Weapons technology
                if (bool_Race_Space_Combat_Poor) then
                  set coop_tech := COOP_TECH_WEAPONS
                  set needed_tech := "Weapons"
                else
                  // Any tech
                  set coop_tech := COOP_TECH_ANY
                  set needed_tech := "Any"
                endif
              endif
            endif
          endif
        endif
        // Special Requests
        // Players we have a high level of cooperation with
        if (coop_level = COOP_LEVEL_HIGH) then
          // If the player is at war with our primary enemy encourage more attacks
          if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Enemy) = POLITICAL_STATUS_TYPE_WAR) then
            set coop_enemy_target := lng_Politics_Primary_Enemy
            // Set a flag for to attack our mutual (primary) enemy
            if (bool_Race_Space_Combat_Poor) or (lng_Combat_Primary_Enemy = coop_enemy_target) then
              set coop_spec_req := COOP_SPEC_REQ_ATTACK
              set special_req := "Attack"
            endif
          else
            // If not our primary enemy, check if this player is at war with our primary weak enemy
            if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Weak_Enemy) = POLITICAL_STATUS_TYPE_WAR) then
              call lst_Politics_Cooperation_Priority_Target.add(coop_enemy_target)
              // Set a flag for to attack our mutual (primary) weak enemy
              if (bool_Race_Space_Combat_Poor) or (lng_Politics_Primary_Weak_Enemy = coop_enemy_target) then
                set coop_spec_req := COOP_SPEC_REQ_ATTACK
                set special_req := "Attack"
              endif
            endif
          endif
          // If no mutual target at war
          if (coop_enemy_target = 0) then
            // Break treaty with our Primary Enemy
            if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Enemy) = POLITICAL_STATUS_TYPE_TREATY) then
              set coop_enemy_target := lng_Politics_Primary_Enemy
              set coop_spec_req := COOP_SPEC_REQ_BREAK_TREATY
              set special_req := "Break Treaty"
            else
              // Break treaty with our weak enemy
              if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Weak_Enemy) = POLITICAL_STATUS_TYPE_TREATY) then
                set coop_enemy_target := lng_Politics_Primary_Weak_Enemy
                set coop_spec_req := COOP_SPEC_REQ_BREAK_TREATY
                set special_req := "Break Treaty"
              endif
            endif
          endif
        else
          // Players we have a medium level of cooperation with
          if (coop_level = COOP_LEVEL_MEDIUM) then
            // Make peace with our friend if they don't have a treaty with them
            if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Friend) <> POLITICAL_STATUS_TYPE_TREATY) then
              set coop_enemy_target := lng_Politics_Primary_Friend
              set coop_spec_req := COOP_SPEC_REQ_PEACE
              set special_req := "Make Peace"
            endif
          else
            // Players we are not really cooperating with
            // Make peace with our friend
            if (Sys_Empire_Politics_Get_Status_With_Player(plr_index, lng_Politics_Primary_Friend) <> POLITICAL_STATUS_TYPE_TREATY) then
              set coop_enemy_target := lng_Politics_Primary_Friend
              set coop_spec_req := COOP_SPEC_REQ_PEACE
              set special_req := "Make Peace"
            endif
          endif
        endif
        // Save our specific cooperation for the selected player
        call lst_Politics_Cooperation_Level.add(coop_level)
        call lst_Politics_Cooperation_Needed_Resource.add(coop_resource)
        call lst_Politics_Cooperation_Needed_Tech.add(coop_tech)
        call lst_Politics_Cooperation_Priority_Target.add(coop_enemy_target)
        call lst_Politics_Cooperation_Special_Request.add(coop_spec_req)
      else
        // Default values
        call lst_Politics_Cooperation_Level.add(0)
        call lst_Politics_Cooperation_Needed_Resource.add(0)
        call lst_Politics_Cooperation_Needed_Tech.add(0)
        call lst_Politics_Cooperation_Priority_Target.add(0)
        call lst_Politics_Cooperation_Special_Request.add(0)
      endif

      // Save to memory
      set base_index := ((plr_index - 1) * 5)
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 11, base_index + 1, lst_Politics_Cooperation_Level.get(plr_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 11, base_index + 2, lst_Politics_Cooperation_Needed_Resource.get(plr_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 11, base_index + 3, lst_Politics_Cooperation_Needed_Tech.get(plr_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 11, base_index + 4, lst_Politics_Cooperation_Priority_Target.get(plr_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 11, base_index + 5, lst_Politics_Cooperation_Special_Request.get(plr_index))

      // For debug output
      if (coop_enemy_target = 0) then
        set coop_enemy_target_name := "None"
        set special_req := "None"
      else
        set coop_enemy_target_name := Sys_Empire_Get_Empire_Name(coop_enemy_target)
      endif

      // Debug output
      if (plr_index <> sys_long_Player_ID) then
        call Sys_Debug_Print("Enemy Analysis", "    - " + Sys_Empire_Get_Empire_Name(plr_index))
        call Sys_Debug_Print("Enemy Analysis", "      - Coop Level = " + Sys_Convert_Long_To_String(coop_level))
        call Sys_Debug_Print("Enemy Analysis", "      - Needed Resource = " + needed_resource)
        call Sys_Debug_Print("Enemy Analysis", "      - Needed Tech = " + needed_tech)
        call Sys_Debug_Print("Enemy Analysis", "      - Special Request = " + special_req)
        call Sys_Debug_Print("Enemy Analysis", "        - Special Request Target = " + coop_enemy_target_name)
      endif
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Analyze_Enemy_Colonization_Potential
//------------------------------------------------------------------------
function Analyze_Enemy_Colonization_Potential returns boolean
params
vars
  num_players:               long
  plr_index:                 long
  planet_list:               longlist
  planet_count:              long
  planet_index:              long
  planet_id:                 long
  atmosphere_type:           long
  atmosphere_type_name:      string
  colonization_ability:      long
  colonization_ability_name: string
begin

  // Get the number of players
  set num_players := Sys_Get_Number_Of_Players()
  // Debug Output
  call Sys_Debug_Print("Enemy Analysis", "Colonization Comparison:")
  call Sys_Debug_Print("Enemy Analysis", "------------------------")

  // Determine the player's breathable atmosphere and colonization ability
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      // Debug output
      call Sys_Debug_Print("Enemy Analysis", "  - " + Sys_Empire_Get_Empire_Name(plr_index))
      // What is their native atmosphere?
      set atmosphere_type := Get_Native_Atmosphere(plr_index)
      // Note it
      if (atmosphere_type > 0) then
        call lst_Politics_Player_Native_Atmosphere.add(atmosphere_type)
      endif
      // What is their colonization ability?
      set colonization_ability := Get_Colonization_Ability(plr_index)
      // Note it
      if (colonization_ability > 0) then
        call lst_Politics_Player_Colonization_Ability.add(colonization_ability)
      endif
      // Debug output
      set atmosphere_type_name := Get_Planet_Atmosphere_Type_Name(atmosphere_type)
      set colonization_ability_name := Get_Colonization_Ability_Name(colonization_ability)
      call Sys_Debug_Print("Enemy Analysis", "    - Atmosphere = " + atmosphere_type_name + "; Colonization Type(s) = " + colonization_ability_name)
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Analyze_Enemy_Proximity
//------------------------------------------------------------------------
function Analyze_Enemy_Proximity returns boolean
params
vars
  num_players:               long
  plr_index:                 long
  overlap_pct:               long
  avg_sys_dist:              long
begin

  // Get the number of players
  set num_players := Sys_Get_Number_Of_Players()
  // Debug Output
  call Sys_Debug_Print("Enemy Analysis", "---------------------")
  call Sys_Debug_Print("Enemy Analysis", "Proximity Comparison:")

  // Check for various proximity factors
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      // Debug output
      call Sys_Debug_Print("Enemy Analysis", "  - " + Sys_Empire_Get_Empire_Name(plr_index))
      if (plr_index <> sys_long_Player_ID) then
        // What % of our systems are shared with the player?
        set overlap_pct := Compute_Player_Overlap(plr_index)
        // Record it
        call lst_Politics_Player_Overlap_Pct.add(overlap_pct)
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - % systems shared = " + Sys_Convert_Long_To_String(overlap_pct))
        // Note the average systems distance to the player's Colonies from our home system
        set avg_sys_dist := Compute_Average_Distance_To_Player(plr_index)
        // Record it
        call lst_Politics_Player_Avg_Sys_Dist.add(avg_sys_dist)
        // Debug output
        call Sys_Debug_Print("Enemy Analysis", "    - Avg sys distance to their colonies = " + Sys_Convert_Long_To_String(avg_sys_dist))
      else
        // Add a record for ourselves to maintain correct indexing
        call lst_Politics_Player_Overlap_Pct.add(100)
        call lst_Politics_Player_Avg_Sys_Dist.add(0)
      endif
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Analyze_Enemy_Production
//------------------------------------------------------------------------
function Analyze_Enemy_Production returns boolean
vars
  num_players:               long
  plr_index:                 long
  our_resource_production:   resources
  our_minerals:              long
  our_organics:              long
  our_radioactives:          long
  our_resources:             long
  our_research_pts:          long
  our_tech_levels:           long
  our_intel_pts:             long
  our_num_ships:             long
  pct_research:              long
  pct_intel:                 long
  their_resource_production: resources
  their_minerals:            long
  their_organics:            long
  their_radioactives:        long
  their_tech_levels:         long
  intel_pts_against_us:      long
  their_num_ships:           long
  lst_minerals:              longlist
  lst_organics:              longlist
  lst_radioactives:          longlist
  lst_research_pts:          longlist
  lst_tech_levels:           longlist
  lst_intel_pts:             longlist
  lst_ships:                 longlist
  lst_num_ships:             longlist
  median_minerals:           long
  low_minerals:              long
  high_minerals:             long
  median_organics:           long
  low_organics:              long
  high_organics:             long
  median_radioactives:       long
  low_radioactives:          long
  high_radioactives:         long
  median_resources:          long
  low_resources:             long
  high_resources:            long
  median_research_pts:       long
  low_research_pts:          long
  high_research_pts:         long
  median_tech_levels:        long
  low_tech_levels:           long
  high_tech_levels:          long
  median_intel_pts:          long
  low_intel_pts:             long
  high_intel_pts:            long
  median_num_ships:          long
  low_num_ships:             long
  high_num_ships:            long
begin

  // Get the number of players
  set num_players := Sys_Get_Number_Of_Players()

  // Get our empire's research and intel generation
  set our_resource_production := Sys_AI_Empire_Stats_Get_Colony_Resource_Production(sys_long_Player_ID)
  set our_minerals := Sys_Trunc(our_resource_production.get(POINT_TYPE_MINERALS))
  set our_organics := Sys_Trunc(our_resource_production.get(POINT_TYPE_ORGANICS))
  set our_radioactives := Sys_Trunc(our_resource_production.get(POINT_TYPE_RADIOACTIVES))
  set our_resources := our_minerals + our_organics + our_radioactives
  set our_research_pts := Sys_Get_Empire_Current_Points(sys_long_Player_ID, POINT_TYPE_RESEARCH)
  set our_tech_levels := Compute_Number_Of_Techs_Researched(sys_long_Player_ID)
  set our_intel_pts := Sys_Get_Empire_Current_Points(sys_long_Player_ID, POINT_TYPE_INTELLIGENCE)
  set our_num_ships := Sys_Get_List_Of_Space_Objects_Of_Type(SPACE_OBJECT_TYPE_SHIP, lst_ships, TRUE, FALSE, sys_long_Player_ID)

  // Debug output
  call Sys_Debug_Print("Enemy Analysis", "----------------------")
  call Sys_Debug_Print("Enemy Analysis", "Production Comparison:")

  // Compile lists of resource/point production by player to calculate median value
  if (num_players > 0) and (not bool_Are_We_Neutral_Player) then
    for plr_index := 1 to num_players do
      call lst_ships.clear()
      // Don't include neutral players
      if (sys_long_Player_ID <> plr_index) and (not Sys_Are_We_Neutral_Empire(plr_index)) then
        // Resources
        set their_resource_production := Sys_AI_Empire_Stats_Get_Colony_Resource_Production(plr_index)
        set their_minerals := Sys_Trunc(their_resource_production.get(POINT_TYPE_MINERALS))
        set their_organics := Sys_Trunc(their_resource_production.get(POINT_TYPE_ORGANICS))
        set their_radioactives := Sys_Trunc(their_resource_production.get(POINT_TYPE_RADIOACTIVES))
        call lst_minerals.add(their_minerals)
        call lst_organics.add(their_organics)
        call lst_radioactives.add(their_radioactives)
        // Research
        call lst_research_pts.add(Sys_Get_Empire_Current_Points(plr_index, POINT_TYPE_RESEARCH))
        set their_tech_levels := Compute_Number_Of_Techs_Researched(plr_index)
        call lst_Politics_Player_Tech_Levels.add(their_tech_levels)
        call lst_tech_levels.add(their_tech_levels)
        // Intel
        set  intel_pts_against_us := intel_pts_against_us + Sys_Divide_Long(Sys_Get_Empire_Intelligence_Spending_Against_Player(plr_index, sys_long_player_ID) * Sys_Get_Empire_Current_Points(plr_index, POINT_TYPE_INTELLIGENCE), 100)
        call lst_intel_pts.add(Sys_Get_Empire_Current_Points(plr_index, POINT_TYPE_INTELLIGENCE))
        // Ships
        set their_num_ships := Sys_Get_List_Of_Space_Objects_Of_Type(SPACE_OBJECT_TYPE_SHIP, lst_ships, TRUE, FALSE, plr_index)
        call lst_num_ships.add(their_num_ships)
      else
        call lst_Politics_Player_Tech_Levels.add(our_tech_levels)
      endif
    endfor

    // Determine the median level of resource and point production
    if (lst_minerals.count() > 0) then
      set median_minerals := Get_Median_Value(lst_minerals)
      set median_organics := Get_Median_Value(lst_organics)
      set median_radioactives := Get_Median_Value(lst_radioactives)
      set median_resources := median_minerals + median_organics + median_radioactives
      set median_research_pts := Get_Median_Value(lst_research_pts)
      set median_tech_levels := Get_Median_Value(lst_tech_levels)
      set median_intel_pts := Get_Median_Value(lst_intel_pts)
      set median_num_ships := Get_Median_Value(lst_num_ships) 
    endif

    // Set low/high values for comparison
    set low_minerals := Sys_Trunc(median_minerals * 0.8)
    set high_minerals := Sys_Trunc(median_minerals * 1.25)
    set low_organics := Sys_Trunc(median_organics * 0.8)
    set high_organics := Sys_Trunc(median_organics * 1.25)
    set low_radioactives := Sys_Trunc(median_radioactives * 0.8)
    set high_radioactives := Sys_Trunc(median_radioactives * 1.25)
    set low_resources := Sys_Trunc(median_resources * 0.8)
    set high_resources := Sys_Trunc(median_resources * 1.25)
    set low_research_pts := Sys_Trunc(median_research_pts * 0.8)
    set high_research_pts := Sys_Trunc(median_research_pts * 1.25)
    set low_tech_levels := Sys_Trunc(median_tech_levels * 0.8)
    set high_tech_levels := Sys_Trunc(median_tech_levels * 1.25)
    set low_intel_pts := Sys_Trunc(median_intel_pts * 0.8)
    set high_intel_pts := Sys_Trunc(median_intel_pts * 1.25)
    set low_num_ships := Sys_Trunc(median_num_ships * 0.8)
    set high_num_ships := Sys_Trunc(median_num_ships * 1.25)

    // Minerals
    call Sys_Debug_Print("Enemy Analysis", "  - Our Minerals = " + Sys_Convert_Long_To_String(our_minerals) + "; Median Minerals = " + Sys_Convert_Long_To_String(median_minerals))

    if (our_minerals < low_minerals) then
      set bool_Enemy_Ahead_In_Minerals := TRUE
      call Sys_Debug_Print("Enemy Analysis", "    - Behind")
    else
      if (our_minerals > high_minerals) then
        call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
      else
        call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
      endif
    endif

    // Organics
    call Sys_Debug_Print("Enemy Analysis", "  - Our Organics = " + Sys_Convert_Long_To_String(our_organics) + "; Median Organics = " + Sys_Convert_Long_To_String(median_organics))

    if (our_organics < low_organics) then
      set bool_Enemy_Ahead_In_Organics := TRUE
      call Sys_Debug_Print("Enemy Analysis", "    - Behind")
    else
      if (our_organics > high_organics) then
        call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
      else
        call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
      endif
    endif

    // Radioactives
    call Sys_Debug_Print("Enemy Analysis", "  - Our Radioactives = " + Sys_Convert_Long_To_String(our_radioactives) + "; Median Radioactives = " + Sys_Convert_Long_To_String(median_radioactives))

    if (our_radioactives < low_radioactives) then
      set bool_Enemy_Ahead_In_Radioactives := TRUE
      call Sys_Debug_Print("Enemy Analysis", "    - Behind")
    else
      if (our_radioactives > high_radioactives) then
        call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
      else
        call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
      endif
    endif

    // Overall Resources
    call Sys_Debug_Print("Enemy Analysis", "  - Our Resources = " + Sys_Convert_Long_To_String(our_resources) + "; Median Resources = " + Sys_Convert_Long_To_String(median_resources))

    if (our_resources < low_resources) then
      set bool_Enemy_Ahead_In_Resources := TRUE
      call Sys_Debug_Print("Enemy Analysis", "    - Behind")
    else
      if (our_radioactives > high_radioactives) then
        call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
      else
        call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
      endif
    endif

    // Research Points and Levels
    if (not bool_Race_At_Max_Tech) then
      call Sys_Debug_Print("Enemy Analysis", "  - Our Research Pts = " + Sys_Convert_Long_To_String(our_research_pts) + "; Median Research Pts = " + Sys_Convert_Long_To_String(median_research_pts))
      call Sys_Debug_Print("Enemy Analysis", "  - Our Research Levels = " + Sys_Convert_Long_To_String(our_tech_levels) + "; Median Research Levels = " + Sys_Convert_Long_To_String(median_tech_levels))

      if (our_research_pts < low_research_pts) and (our_tech_levels < low_tech_levels) then
        set bool_Enemy_Ahead_In_Research := TRUE
        call Sys_Debug_Print("Enemy Analysis", "    - Behind")
        // Are we really far behind?
        if ((our_tech_levels * 2) < low_tech_levels) then
          set bool_Enemy_Far_Ahead_In_Research := TRUE
          call Sys_Debug_Print("Enemy Analysis", "    - Really Behind!")
        endif
      else
        if (our_research_pts > high_research_pts) and (our_tech_levels > high_tech_levels) then
          set bool_Enemy_Behind_In_Research := TRUE
          call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
        else
          call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
        endif
      endif
    endif

    // Intel Points
    if (bool_Intel_Is_Allowed) then
      call Sys_Debug_Print("Enemy Analysis", "  - Our Intel Pts = " + Sys_Convert_Long_To_String(our_intel_pts) + "; Median Intel Pts = " + Sys_Convert_Long_To_String(median_intel_pts))

      if (our_intel_pts < low_intel_pts) then
        set bool_Enemy_Ahead_In_Intel := TRUE
        call Sys_Debug_Print("Enemy Analysis", "    - Behind")
        // Are we really far behind?
        if ((our_intel_pts * 2) < low_intel_pts) then
          set bool_Enemy_Far_Ahead_In_Intel := TRUE
          call Sys_Debug_Print("Enemy Analysis", "    - Really Behind!")
        endif
      else
        if (our_intel_pts > high_intel_pts) then
          set bool_Enemy_Behind_In_Intel := TRUE
          call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
        else
          call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
        endif
      endif
      // Are we facing much more intel against than we are generating?
      if ((our_intel_pts * 2) < intel_pts_against_us) then
        set bool_Enemy_Intel_Overload := TRUE
        call Sys_Debug_Print("Enemy Analysis", "    - Intel Overload!")
      endif
    endif
  
    // Number of Ships
    call Sys_Debug_Print("Enemy Analysis", "  - Our # Ships = " + Sys_Convert_Long_To_String(our_num_ships) + "; Median # Ships = " + Sys_Convert_Long_To_String(median_num_ships))

    if (our_num_ships < low_num_ships) then
      set bool_Enemy_Ahead_In_Ships := TRUE
      call Sys_Debug_Print("Enemy Analysis", "    - Behind")
      // Are we really far behind?
      if ((our_num_ships * 2) < low_num_ships) then
        set bool_Enemy_Far_Ahead_In_Ships := TRUE
        call Sys_Debug_Print("Enemy Analysis", "    - Really Behind!")
      endif
    else
      if (our_num_ships > high_num_ships) then
        call Sys_Debug_Print("Enemy Analysis", "    - Ahead")
      else
        call Sys_Debug_Print("Enemy Analysis", "    - Comparable")
      endif
    endif
  else
    call Sys_Debug_Print("Enemy Analysis", "    - Skip because we are a neutral player")
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Analyze_Enemy_Designs
//------------------------------------------------------------------------
function Analyze_Enemy_Designs returns boolean
vars
  num_players:               long
  plr_index:                 long
  plr_design_count:          long
  design_index:              long
  design_id:                 long
  design_age:                long
  design_last_seen:          long
  design_type:               string
  seeker_count:              long := 0
  direct_fire_count:         long := 0
  design_count_mod:          long := 1
  emissive_armor_count:      long := 0
  crystalline_armor_count:   long := 0
  primary_crystalline:       boolean := FALSE
  organic_armor_count:       long := 0
  primary_organic:           boolean := FALSE
  normal_shield_count:       long := 0
  phased_shield_count:       long := 0
  skip_armor_count:          long := 0
  primary_skip_armor:        boolean := FALSE
  skip_shield_count:         long := 0
  primary_skip_shield:       boolean := FALSE
  skip_all_count:            long := 0
  primary_skip_all:          boolean := FALSE
  long_range_seeker_count:   long := 0
  shield_depleting_count:    long := 0
  supply_depleting_count:    long := 0
  engine_damaging_count:     long := 0
  master_computer_count:     long := 0
  our_sensor_level:          long := 0
  design_sensor_level:       long := 0
  max_enemy_sensor_level:    long := 0
  check_design:              boolean
  check_combat:              boolean
  primary_enemy:             boolean
  skip_reason:               string
begin

  // Get the number of players
  set num_players := Sys_Get_Number_Of_Players()
  set our_sensor_level := Sys_Get_Empire_Research_Tech_Level(sys_long_player_ID, Sys_Get_Tech_ID("Sensors"))

  // Look at our enemies' designs and see what components they are using
  if (num_players > 0) then
    for plr_index := 1 to num_players do
      if (plr_index <> sys_long_Player_ID) then
        set plr_design_count := Sys_Get_Player_Designs_Count(plr_index)
        set design_count_mod := 1

        // Only do the design check if the player is a medium or high priority target
        if Sys_Empire_Politics_Is_Player_Enemy(sys_long_Player_ID, plr_index) then
          // Debug Output
          call Sys_Debug_Print("Enemy Analysis", "----------------------")
          call Sys_Debug_Print("Enemy Analysis", "Enemy Design Analysis:")
          // Add extra weight for enemy designs
          if Sys_Empire_Politics_Is_Player_Enemy(sys_long_Player_ID, plr_index) then
            set design_count_mod := design_count_mod + 1
            call Sys_Debug_Print("Enemy Analysis", "  - " + Sys_Empire_Get_Empire_Name(plr_index) + " (Enemy)")
          endif
          // Add extra weight for our primary enemy or primary weak enemy's designs
          if (plr_index = lng_Politics_Primary_Enemy) or (plr_index = lng_Politics_Primary_Weak_Enemy) then
            set primary_enemy := TRUE
            set design_count_mod := design_count_mod + 1
            call Sys_Debug_Print("Enemy Analysis", "    - Primary Enemy")
          endif
          // Add extra weight for our primary combat enemy's designs
          if (plr_index = lng_Combat_Primary_Enemy) then
            set primary_enemy := TRUE
            set design_count_mod := design_count_mod + 1
            call Sys_Debug_Print("Enemy Analysis", "    - Primary Combat Enemy")
          endif

          // Look at our non-obsolete (or not as old) enemy designs to see what they are using...
          if (plr_design_count > 0) then
            for design_index := 1 to plr_design_count do
              set design_id := Sys_Get_Player_Design_ID(plr_index, design_index)
              set design_age := sys_long_Game_Date - Sys_Get_Vehicle_Design_Creation_Date(plr_index, design_id)
              set design_last_seen := Sys_Get_Vehicle_Design_Date_Last_Seen(design_id, sys_long_Player_ID)
              set design_type := Sys_Get_Vehicle_Design_AI_Design_Type(design_id)
              // If the AI design type is blank, use the general type...
              if (design_type = "") then
                set design_type := Sys_Get_Vehicle_Design_General_Type(plr_index, design_id)
              endif
              // Set the design type to a basic one for comparison
              set design_type := Get_General_AI_Design_Type(design_type)
              set check_design := TRUE
              set check_combat := FALSE

              // Skip designs we haven't seen
              if (Sys_Get_Vehicle_Design_Date_Last_Seen(design_id, sys_long_Player_ID) = 0) then
                set check_design := FALSE
                set skip_reason := "(not seen)"
              endif
              // Skip obsolete designs (but only if they are older than 50 turns)
              if Sys_Has_Vehicle_Design_Been_Used(design_id) then
                if Sys_Is_Vehicle_Design_Obsolete(design_id) and (design_age > 50) then
                  set check_design := FALSE
                  set skip_reason := "(obsolete and/or older design)"
                endif
              endif
              // Check weapons/defenses on primary combat designs
              if (design_type = "Ship (Attack)") or (design_type = "Ship (Defense)") or (design_type = "Ship (Seeker)") or (design_type = "Ship (Bombardment)") then
                set check_combat := TRUE
              endif

              // Analyze the design for specific components
              if (check_design) then
                // Debug output
                call Sys_Debug_Print("Enemy Analysis", "      - Check design " + Sys_Get_Vehicle_Design_Name(design_id) + " (" + design_type + ")")
                call Sys_Debug_Print("Enemy Analysis", "        - Age = " + Sys_Convert_Long_To_String(design_age))
                call Sys_Debug_Print("Enemy Analysis", "        - Last seen = " + Sys_Convert_Long_To_String(design_last_seen))
                call Sys_Debug_Print("Enemy Analysis", "        - Ordnance = " + Sys_Convert_Long_To_String(Sys_Get_Vehicle_Design_Total_Ordnance_Usage(design_id, plr_index)))
                // Note combat ships
                if (check_combat) then
                  call Sys_Debug_Print("Enemy Analysis", "        - Combat design")
                endif
                // Human player using boarding parties?
                if (not Sys_Are_We_Computer_Player(plr_index)) then
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Boarding Parties") then
                    set bool_Enemy_Uses_Boarding_Parties := TRUE
                  endif
                endif
                // Sensor level?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Basic Sensors") then
                  set design_sensor_level := Sys_Get_Empire_Research_Tech_Level(plr_index, Sys_Get_Tech_ID("Sensors"))
                  // Track the best sensor level of our enemies
                  if (design_sensor_level > max_enemy_sensor_level) then
                    set max_enemy_sensor_level := design_sensor_level
                  endif
                endif
                // Cloaking devices?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Cloaking Device") then
                  set bool_Enemy_Uses_Cloaking_Devices := TRUE
                  call Sys_Debug_Print("Enemy Analysis", "        - Cloaking Device")
                endif
                // Advanced sensors?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Tachyon Sensors") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Psychic Receptors") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Temporal Sensors") then
                  set bool_Enemy_Uses_Advanced_Sensors := TRUE
                  call Sys_Debug_Print("Enemy Analysis", "        - Advanced Sensors")
                endif
                // Long range scanners?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Long Range Scanners") then
                  set bool_Enemy_Uses_Long_Range_Scanners := TRUE
                  call Sys_Debug_Print("Enemy Analysis", "        - Long Range Scanners")
                endif
                // Master or Control Computers?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Master Computer") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Control Computer") then
                  set master_computer_count := master_computer_count + design_count_mod
                  call Sys_Debug_Print("Enemy Analysis", "        - Master Computer")
                endif
                // Evil stellar manipulation components?
                if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Tectonic Bomb") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Stellar Nucleonic Torpedo") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Inverted Quantum Beam") or or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Nucleonic Thresher Torpedo") then
                  set bool_Enemy_Uses_Evil_Stellar_Manipulation := TRUE
                  call Sys_Debug_Print("Enemy Analysis", "        - Evil Stellar Manipulation")
                endif
                // Extra checks for combat ships
                if (check_combat) then
                  // Emissive armor?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Emissive Armor") then
                    set emissive_armor_count := emissive_armor_count + design_count_mod
                  endif
                  // Crystalline armor?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Light Crystalline Armor") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Heavy Crystalline Armor") then
                    set crystalline_armor_count := crystalline_armor_count + design_count_mod
                    set primary_crystalline := TRUE
                    call Sys_Debug_Print("Enemy Analysis", "        - Crystalline Armor")
                  endif
                  // Organic armor?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Light Organic Armor") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Heavy Organic Armor") then
                    set organic_armor_count := organic_armor_count + design_count_mod
                    set primary_organic := TRUE
                    call Sys_Debug_Print("Enemy Analysis", "        - Organic Armor")
                  endif
                  // Normal shields?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Shield Generator") then
                    set normal_shield_count := normal_shield_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Shields")
                  endif
                  // Phased shields?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Phased Shield Generator") then
                    set phased_shield_count := phased_shield_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Phased Shields")
                  endif
                  // Skip armor weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Shard Cannon") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Crystalline Torpedo") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Small Shard Cannon") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Small Crystalline Torpedo") then
                    set skip_armor_count := skip_armor_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Skip Armor Weapons")
                    // Special flag if one of our primary enemies is using these weapons
                    if (primary_enemy) then
                      set primary_skip_armor := TRUE
                    endif
                  endif
                  // Skip shield weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Phased-Polaron Beam") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Small Phased-Polaron Beam") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Gamma Pulse Torpedo") then
                    set skip_shield_count := skip_shield_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Skip Shield Weapons")
                    // Special flag if one of our primary enemies is using these weapons
                    if (primary_enemy) then
                      set primary_skip_shield := TRUE
                    endif
                  endif
                  // Null-Space weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Null-Space Projector") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Small Null-Space Projector") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Null-Space Cannons") then
                    set skip_all_count := skip_all_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Skip All Weapons")
                    // Special flag if one of our primary enemies is using these weapons
                    if (primary_enemy) then
                      set primary_skip_all := TRUE
                    endif
                  endif
                  // Long range seekers?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Plasma Missile") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Seeking Parasite") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Crystalline Torpedo") then
                    set long_range_seeker_count := long_range_seeker_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Long Range Seekers")
                  endif
                  // Shield depleting weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Shield Depleter") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Shield Disrupter") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Crystalline Siphon") then
                    set shield_depleting_count := shield_depleting_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Shield Depleting Weapons")
                  endif
                  // Supply depleting weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Power Lamprey") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Power Leech Beam") then
                    set supply_depleting_count := supply_depleting_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Supply Depleting Weapons")
                  endif
                  // Engine damage weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Ionic Disperser") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Ionic Pulse Missile") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Massive Ionic Disperser") then
                    set engine_damaging_count := engine_damaging_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Engine Damaging Weapons")
                  endif
                  // Viral weapons?
                  if Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Toxic Injectors") or Sys_Does_Vehicle_Design_Have_Component_With_Name(design_id, "Plague Bomb") then
                    set bool_Enemy_Uses_Viral_Weapons := TRUE
                    call Sys_Debug_Print("Enemy Analysis", "        - Viral Weapons")
                  endif
                  // Note if the design uses significant ordnance amounts
                  if (Sys_Get_Vehicle_Design_Total_Ordnance_Usage(design_id, plr_index) >= 5) then
                    set seeker_count := seeker_count + design_count_mod
                    call Sys_Debug_Print("Enemy Analysis", "        - Seeker")
                  else
                    call Sys_Debug_Print("Enemy Analysis", "        - Direct Fire")
                    set direct_fire_count := direct_fire_count + design_count_mod
                  endif
                endif
              else
                // Temp Debug output
                // call Sys_Debug_Print("Enemy Analysis", "        - Skip Check " + skip_reason)
              endif
            endfor
          endif
        endif
      endif
    endfor
  endif

  // Debug Output
  call Sys_Debug_Print("Enemy Analysis", "---------------------")
  call Sys_Debug_Print("Enemy Analysis", "Enemy Design Summary:")

  // Note if our enemies are using seeking or direct fire weapons
  if (seeker_count > direct_fire_count) then
    set bool_Enemy_Uses_Seeker_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use mostly Seeker weapons")
    call Sys_Debug_Print("Enemy Analysis", "    - Seeker = " + Sys_Convert_Long_To_String(seeker_count) + "; Direct = " + Sys_Convert_Long_To_String(direct_fire_count))
  else
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use mostly Direct Fire weapons")
    call Sys_Debug_Print("Enemy Analysis", "    - Direct = " + Sys_Convert_Long_To_String(direct_fire_count) + "; Seeker = " + Sys_Convert_Long_To_String(seeker_count))
  endif

  // Note if our enemies have faster ships
  if (lng_Max_Enemy_Ship_Movement - lng_Max_Ship_Movement >= 1) then
    set bool_Enemy_Ships_Are_Faster := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Have faster ships")
  endif
  if (lng_Max_Enemy_Ship_Movement - lng_Max_Ship_Movement >= 2) then
    set bool_Enemy_Ships_Are_Much_Faster := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Have much faster ships")
  endif

  // Note if our enemies have slower ships
  if (lng_Max_Ship_Movement - lng_Max_Enemy_Ship_Movement >= 1) then
    set bool_Enemy_Ships_Are_Slower := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Have slower ships")
  endif
  if (lng_Max_Ship_Movement - lng_Max_Enemy_Ship_Movement >= 2) then
    set bool_Enemy_Ships_Are_Much_Slower := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Have much slower ships")
  endif

  // For races with no enemies determine shield use modifiers by friendly
  if (lng_AI_Num_Of_Enemies = 0) then
    if (bool_Friend_Uses_Mostly_Shields) then
      set bool_Enemy_Uses_Mostly_Shields := TRUE
      set bool_Enemy_Uses_Mostly_Armor := FALSE
    endif
  endif

  if (bool_Enemy_Uses_Mostly_Armor) then
    if (lng_AI_Num_Of_Enemies = 0) then
      call Sys_Debug_Print("Enemy Analysis", "  - Armor > Shields*")
    else
      call Sys_Debug_Print("Enemy Analysis", "  - Armor < Shields")
    endif
  endif
  if (bool_Friend_Uses_Mostly_Armor) then
    call Sys_Debug_Print("Enemy Analysis", "  - Friends using more armor than shields")
  endif
  if (bool_Enemy_Uses_Mostly_Shields) then
    if (lng_AI_Num_Of_Enemies = 0) then
      call Sys_Debug_Print("Enemy Analysis", "  - Enemies using more shields than armor*")
    else
      call Sys_Debug_Print("Enemy Analysis", "  - Enemies using more shields than armor")
    endif
  endif
  if (bool_Friend_Uses_Mostly_Shields) then
    call Sys_Debug_Print("Enemy Analysis", "  - Friends using more shields than armor")
  endif

  // Note significant enemy trends
  // Emissive armor
  if (emissive_armor_count > plr_design_count * 0.3) then
    set bool_Enemy_Uses_Emissive_Armor := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Emissive Armor")
  endif
  // Crystalline armor
  if (crystalline_armor_count > plr_design_count * 0.3) or (primary_crystalline) then
    set bool_Enemy_Uses_Crystalline_Armor := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Crystalline Armor")
  endif
  // Organic armor
  if (organic_armor_count > plr_design_count * 0.3) or (primary_organic) then
    set bool_Enemy_Uses_Organic_Armor := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Organic Armor")
  endif
  // Shield type
  if (phased_shield_count > normal_shield_count) then
     set bool_Enemy_Uses_Phased_Shields := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Phased Shields")
   else
     set bool_Enemy_uses_Normal_Shields := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Normal Shields")
  endif
  // Long range seekers
  if (long_range_seeker_count > plr_design_count * 0.3) then
    set bool_Enemy_Uses_Long_Range_Seeker_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use long-range seekers")
  endif
  // Armor skipping weapons
  if (skip_armor_count > plr_design_count * 0.3) or (primary_skip_armor) then
    set bool_Enemy_Uses_Skip_Armor_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use armor skipping weapons")
  endif
  // Shield skipping weapons
  if (skip_shield_count > plr_design_count * 0.3) or (primary_skip_shield) then
    set bool_Enemy_Uses_Skip_Shield_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use shield skipping weapons")
  endif
  // Skip all weapons
  if (skip_all_count > plr_design_count * 0.1) or (primary_skip_all) then
    set bool_Enemy_Uses_Skip_All_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use skip all weapons")
  endif
  // Shield depleting weapons
  if (shield_depleting_count > plr_design_count * 0.3) then
    set bool_Enemy_Uses_Shield_Depleting_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use shield depleting weapons")
  endif
  // Supply depleting weapons
  if (supply_depleting_count > plr_design_count * 0.3) then
    set bool_Enemy_Uses_Supply_Depleting_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use supply depleting weapons")
  endif
  // Engine damaging weapons
  if (engine_damaging_count > plr_design_count * 0.3) then
    set bool_Enemy_Uses_Only_Engine_Weapons := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use engine damaging weapons")
  endif
  // Master or Control Computers
  if (master_computer_count > plr_design_count * 0.5) then
    set bool_Enemy_Uses_Master_Computers := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Use Master or Control Computers")
  endif
  // Cloaking Devices
  if (bool_Enemy_Uses_Cloaking_Devices) then
    call Sys_Debug_Print("Enemy Analysis", "  - Use Cloaking Devices")
  endif
  // Sensors
  if (max_enemy_sensor_level > (our_sensor_level + 3)) then
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "  - Have better sensors")
    set bool_Enemy_Ships_Have_Better_Sensors := TRUE
  else
    if (our_sensor_level > (max_enemy_sensor_level + 3)) then
      // Debug output
      call Sys_Debug_Print("Enemy Analysis", "  - We have better sensors")
    endif
  endif
  // Advanced Sensors
  if (bool_Enemy_Uses_Advanced_Sensors) then
    call Sys_Debug_Print("Enemy Analysis", "  - Use advanced sensors")
  endif
  if (bool_Enemy_Uses_Long_Range_Scanners) then
    call Sys_Debug_Print("Enemy Analysis", "  - Use long range scanners")
  endif
  if (bool_Enemy_Uses_Boarding_Parties) then
    call Sys_Debug_Print("Enemy Analysis", "  - Use Boarding Parties")
  endif
  if (bool_Enemy_Uses_Evil_Stellar_Manipulation) then
    call Sys_Debug_Print("Enemy Analysis", "  - Use evil stellar manipulation")
  endif

  return TRUE
end

//------------------------------------------------------------------------
// Analyze_Combat_Performance
//------------------------------------------------------------------------
function Analyze_Combat_Performance returns boolean
vars
  combat_count:              long
  combat_index:              long
  storage_index:             long
  lst_combat_date:           longlist
  lst_combat_type:           longlist
  lst_combat_result:         longlist
  lst_combat_point_value:    longlist
  lst_combat_colony_lost:    longlist
  lst_combat_plr1:           longlist
  lst_combat_plr2:           longlist
  lst_combat_plr3:           longlist
  lst_combat_plr4:           longlist
  lst_log_entries:           longlist
  log_count:                 long
  log_index:                 long
  log_id:                    long
  log_type:                  long
  log_sys_loc:               long
  log_sect_loc:              long
  log_plr_caused:            long
  log_alliance_caused:       long
  plr_count:                 long
  plr_index:                 long
  plr1:                      long
  plr2:                      long
  plr3:                      long
  plr4:                      long
  plr1_name:                 string
  plr2_name:                 string
  plr3_name:                 string
  plr4_name:                 string
  combat_pts:                long
  count_combat:              boolean := FALSE
  total_combats_vs_plr:      long
  total_space_combat_pts:    long
  total_ground_combat_pts:   long
  total_colonies_lost:       long
  max_combats_vs_plr:        long := 0
begin

  // Load our previously saved combat statistics
  set combat_count := Sys_Get_AI_Storage_Long(sys_long_Player_ID, 1, 10)

  if (combat_count > 0) then
    for combat_index := 1 to combat_count do
      set storage_index := (combat_index - 1) * 9
      // Only add recent combats (last 25 turns)
      if ((sys_long_Game_Date - 25) <= Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 1)) then
        call lst_combat_date.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 1))
        call lst_combat_type.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 2))
        call lst_combat_result.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 3))
        call lst_combat_point_value.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 4))
        call lst_combat_colony_lost.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 5))
        call lst_combat_plr1.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 6))
        call lst_combat_plr2.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 7))
        call lst_combat_plr3.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 8))
        call lst_combat_plr4.add(Sys_Get_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 9))
      endif
    endfor
  endif

  // Get our current log entries
  call Sys_Empire_Log_Get_Log_Entries_For_This_Turn(sys_long_Player_ID, lst_log_entries)

  // Go through our combat log entries and count the number of wins, losses, stalemates, and if colonies were lost
  set log_count := lst_log_entries.count()

  if (log_count > 0) then
    for log_index := 1 to log_count do
      // Get the log entry's details
      set log_id := lst_log_entries.get(log_index)
      set log_type := Sys_Empire_Log_Get_Log_Entry_Type(sys_long_Player_ID, log_id)
      set log_sys_loc := Sys_Empire_Log_Get_Log_Entry_System_Location(sys_long_Player_ID, log_id)
      set log_sect_loc := Sys_Empire_Log_Get_Log_Entry_Sector_Location(sys_long_Player_ID, log_id)
      set log_plr_caused := Sys_Empire_Log_Get_Log_Entry_Caused_By_Player(sys_long_Player_ID, log_id)
      set log_alliance_caused := Sys_Empire_Log_Get_Log_Entry_Caused_By_Alliance(sys_long_Player_ID, log_id)
      set combat_pts := 0
      set count_combat := FALSE

      // Which players were involved?
      call Sys_Get_Log_Players_In_Combat(sys_long_Player_ID, log_id, plr1, plr2, plr3, plr4)

      // Only count combat data from battles we are involved in
      if (log_type >= 64 and log_type <= 68) or (log_type >= 14 and log_type <= 18) then
        if (sys_long_Player_ID = plr1) or (sys_long_Player_ID = plr2) or (sys_long_Player_ID = plr3) or (sys_long_Player_ID = plr4) then
          set count_combat := TRUE
        endif
      endif

      if (count_combat) then
        call lst_combat_date.add(sys_long_Game_Date)
        // Record combat type
        if (log_type >= 64 and log_type <= 68) then
          call lst_combat_type.add(SPACE_COMBAT)
        else
          call lst_combat_type.add(GROUND_COMBAT)
        endif
        // Record combat win/loss
        case log_type
          LOG_TYPE_SPACE_COMBAT_DEFENSE_WON:
            call lst_combat_result.add(SPACE_COMBAT_WIN)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Space_Combat_Offense_Win
          LOG_TYPE_SPACE_COMBAT_OFFENSE_WON:
            call lst_combat_result.add(SPACE_COMBAT_WIN)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Space_Combat_Defense_Win
          LOG_TYPE_SPACE_COMBAT_DEFENSE_LOST:
            call lst_combat_result.add(SPACE_COMBAT_LOSS)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Space_Combat_Offense_Lost
          LOG_TYPE_SPACE_COMBAT_OFFENSE_LOST:
            call lst_combat_result.add(SPACE_COMBAT_LOSS)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Space_Combat_Defense_Lost
          LOG_TYPE_SPACE_COMBAT_STALEMATE:
            call lst_combat_result.add(SPACE_COMBAT_STALEMATE)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Space_Combat_Stalemate
          LOG_TYPE_GROUND_COMBAT_DEFENSE_WON:
            call lst_combat_result.add(GROUND_COMBAT_WIN)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Ground_Combat_Offense_Win
          LOG_TYPE_GROUND_COMBAT_OFFENSE_WON:
            call lst_combat_result.add(GROUND_COMBAT_WIN)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Ground_Combat_Defense_Win
          LOG_TYPE_GROUND_COMBAT_DEFENSE_LOST:
            call lst_combat_result.add(GROUND_COMBAT_LOSS)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Ground_Combat_Offense_Lost
          LOG_TYPE_GROUND_COMBAT_OFFENSE_LOST:
            call lst_combat_result.add(GROUND_COMBAT_LOSS)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Ground_Combat_Defense_Lost
          LOG_TYPE_GROUND_COMBAT_STALEMATE:
            call lst_combat_result.add(GROUND_COMBAT_STALEMATE)
            set combat_pts := combat_pts + lng_Combat_Pts_for_Ground_Combat_Stalemate
        endcase
        // Did we lose or destroy a colony?
        if (Sys_Log_Was_Colony_Lost(sys_long_Player_ID, log_id) = 2) then
          call lst_combat_colony_lost.add(COLONY_LOST)
          set combat_pts := combat_pts + lng_Combat_Pts_for_Colony_Lost
        else
          call lst_combat_colony_lost.add(0)
        endif
        // Record the players involved
        call lst_combat_point_value.add(combat_pts)
        call lst_combat_plr1.add(plr1)
        call lst_combat_plr2.add(plr2)
        call lst_combat_plr3.add(plr3)
        call lst_combat_plr4.add(plr4)
      endif
    endfor
  endif

  // Compile combat statistics against each player
  set plr_count := Sys_Get_Number_Of_Players()
  set combat_count := lst_combat_date.count()

  call lst_Space_Combat_Wins_vs_Player.fill(plr_count, 0)
  call lst_Space_Combat_Losses_vs_Player.fill(plr_count, 0)
  call lst_Space_Combat_Stalemates_vs_Player.fill(plr_count, 0)
  call lst_Space_Combat_Pts_vs_Player.fill(plr_count, 0)
  call lst_Ground_Combat_Wins_vs_Player.fill(plr_count, 0)
  call lst_Ground_Combat_Losses_vs_Player.fill(plr_count, 0)
  call lst_Ground_Combat_Stalemates_vs_Player.fill(plr_count, 0)
  call lst_Ground_Combat_Pts_vs_Player.fill(plr_count, 0)
  call lst_Colonies_Lost_vs_Player.fill(plr_count, 0)

  // Sum up our combat records against each player
  if (combat_count > 0) then
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "------------------")
    call Sys_Debug_Print("Enemy Analysis", "  - Combat Record:")
    call Sys_Debug_Print("Enemy Analysis", "    - Past 25 Turns")
    call Sys_Debug_Print("Enemy Analysis", "    - # Combats = " + Sys_Convert_Long_To_String(combat_count))
    // Pending
    if (plr_count > 0) then
      for plr_index := 1 to plr_count do
        // Reset combat count
        set total_combats_vs_plr := 0
        // Combat combat wins/losses/stalemates
        if (sys_long_player_ID <> plr_index) then
          for combat_index := 1 to combat_count do
            if (lst_combat_plr1.get(combat_index) = plr_index) or  (lst_combat_plr2.get(combat_index) = plr_index) or (lst_combat_plr3.get(combat_index) = plr_index) or (lst_combat_plr4.get(combat_index) = plr_index) then
              // Space combat results
              if (lst_combat_type.get(combat_index) = SPACE_COMBAT) then
                case lst_combat_result.get(combat_index)
                  SPACE_COMBAT_WIN:
                    call lst_Space_Combat_Wins_vs_Player.set(plr_index, lst_Space_Combat_Wins_vs_Player.get(plr_index) + 1)
                  SPACE_COMBAT_LOSS:
                    call lst_Space_Combat_Losses_vs_Player.set(plr_index, lst_Space_Combat_Losses_vs_Player.get(plr_index) + 1)
                  SPACE_COMBAT_STALEMATE:
                    call lst_Space_Combat_Stalemates_vs_Player.set(plr_index, lst_Space_Combat_Stalemates_vs_Player.get(plr_index) + 1)
                endcase
                // Add up our space combat points
                call lst_Space_Combat_Pts_vs_Player.set(plr_index, lst_Space_Combat_Pts_vs_Player.get(plr_index) + lst_combat_point_value.get(combat_index))
                set total_space_combat_pts := total_space_combat_pts + lst_combat_point_value.get(combat_index)
                set total_combats_vs_plr := total_combats_vs_plr + 1
              else
                // Ground combat results
                case lst_combat_result.get(combat_index)
                  GROUND_COMBAT_WIN:
                    call lst_Ground_Combat_Wins_vs_Player.set(plr_index, lst_Ground_Combat_Wins_vs_Player.get(plr_index) + 1)
                  GROUND_COMBAT_LOSS:
                    call lst_Ground_Combat_Losses_vs_Player.set(plr_index, lst_Ground_Combat_Losses_vs_Player.get(plr_index) + 1)
                  GROUND_COMBAT_STALEMATE:
                    call lst_Ground_Combat_Stalemates_vs_Player.set(plr_index, lst_Ground_Combat_Stalemates_vs_Player.get(plr_index) + 1)
                endcase
                // Add up our ground combat points
                call lst_Ground_Combat_Pts_vs_Player.set(plr_index, lst_Ground_Combat_Pts_vs_Player.get(plr_index) + lst_combat_point_value.get(combat_index))
                set total_ground_combat_pts := total_ground_combat_pts + lst_combat_point_value.get(combat_index)
                set total_combats_vs_plr := total_combats_vs_plr + 1
              endif
              // Did we lose a colony?
              if (lst_combat_colony_lost.get(combat_index) = COLONY_LOST) then
                call lst_Colonies_Lost_vs_Player.set(plr_index, lst_Colonies_Lost_vs_Player.get(plr_index) + 1)
                set total_colonies_lost := total_colonies_lost + 1
              endif
            endif
          endfor
          // Debug output
          call Sys_Debug_Print("Enemy Analysis", "------")
          call Sys_Debug_Print("Enemy Analysis", "  - Combat Record vs " + Sys_Empire_Get_Empire_Name(plr_index))
          call Sys_Debug_Print("Enemy Analysis", "    - Space Combat = " + Sys_Convert_Long_To_String(lst_Space_Combat_Wins_vs_Player.get(plr_index)) + "W-" + Sys_Convert_Long_To_String(lst_Space_Combat_Losses_vs_Player.get(plr_index)) + "L-" + Sys_Convert_Long_To_String(lst_Space_Combat_Stalemates_vs_Player.get(plr_index)) + "S")
          call Sys_Debug_Print("Enemy Analysis", "    - Space Combat Pts = " + Sys_Convert_Long_To_String(lst_Space_Combat_Pts_vs_Player.get(plr_index)))
          call Sys_Debug_Print("Enemy Analysis", "    - Ground Combat = " + Sys_Convert_Long_To_String(lst_Ground_Combat_Wins_vs_Player.get(plr_index)) + "W-" + Sys_Convert_Long_To_String(lst_Ground_Combat_Losses_vs_Player.get(plr_index)) + "L-" + Sys_Convert_Long_To_String(lst_Ground_Combat_Stalemates_vs_Player.get(plr_index)) + "S")
          call Sys_Debug_Print("Enemy Analysis", "    - Ground Combat Pts = " + Sys_Convert_Long_To_String(lst_Ground_Combat_Pts_vs_Player.get(plr_index)))
          call Sys_Debug_Print("Enemy Analysis", "    - Colonies Lost = " + Sys_Convert_Long_To_String(lst_Colonies_Lost_vs_Player.get(plr_index)))
        endif
        // Note our primary enemy combatant
        if (total_combats_vs_plr > max_combats_vs_plr) then
          set max_combats_vs_plr := total_combats_vs_plr
          set lng_Combat_Primary_Enemy := plr_index
        endif
      endfor
    endif
  endif

  // Note our overall combat performance
  call Sys_Debug_Print("Enemy Analysis", "-----------------------")
  call Sys_Debug_Print("Enemy Analysis", "  - Combat Performance:")

  // Note our primary combatant
  if (lng_Combat_Primary_Enemy > 0) then
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Primary Combatant = " + Sys_Empire_Get_Empire_Name(lng_Combat_Primary_Enemy))
  endif

  // Space Combat Trend
  // Good
  if (total_space_combat_pts > 10) then
    set bool_Race_Space_Combat_Good := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Space combat good!")
  endif
  // Poor
  if (total_space_combat_pts < -25) then
    set bool_Race_Space_Combat_Poor := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Space combat poor!")
  endif
  if (combat_count > 0) and (not bool_Race_Space_Combat_Good) and (not bool_Race_Space_Combat_Poor) then
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Space combat mediocre!")
  endif

  // Ground Combat Trend
  // Good
  if (total_ground_combat_pts > 10) then
    set bool_Race_Ground_Combat_Good := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Ground combat good!")
  endif
  // Poor
  if (total_ground_combat_pts < -10) then
    set bool_Race_Ground_Combat_Poor := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Ground combat poor!")
  endif

  // Are we losing colonies?
  if (total_colonies_lost > 0) then
    set bool_Race_Losing_Colonies_In_Combat := TRUE
    // Debug output
    call Sys_Debug_Print("Enemy Analysis", "    -  Losing colonies in combat!")
  endif

  // Save our combat data
  if (combat_count > 0) then
    call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 1, 10, combat_count)
    // Save specific combat data
    for combat_index := 1 to combat_count do
      set storage_index := (combat_index - 1) * 9
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 1, lst_combat_date.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 2, lst_combat_type.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 3, lst_combat_result.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 4, lst_combat_point_value.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 5, lst_combat_colony_lost.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 6, lst_combat_plr1.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 7, lst_combat_plr2.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 8, lst_combat_plr3.get(combat_index))
      call Sys_Set_AI_Storage_Long(sys_long_Player_ID, 10, storage_index + 9, lst_combat_plr4.get(combat_index))
      // Get the names of the empires involved
      set plr1_name := Sys_Empire_Get_Empire_Name(lst_combat_plr1.get(combat_index))
      set plr2_name := Sys_Empire_Get_Empire_Name(lst_combat_plr2.get(combat_index))
      set plr3_name := Sys_Empire_Get_Empire_Name(lst_combat_plr3.get(combat_index))
      set plr4_name := Sys_Empire_Get_Empire_Name(lst_combat_plr4.get(combat_index))
      // Debug output
      call Sys_Debug_Print("Enemy Analysis", "    ------")
      call Sys_Debug_Print("Enemy Analysis", "    - Combat Entry #" + Sys_Convert_Long_To_String(combat_index))
      call Sys_Debug_Print("Enemy Analysis", "    - Date = " + Sys_Convert_Long_To_String(lst_combat_date.get(combat_index)))
      call Sys_Debug_Print("Enemy Analysis", "    - Type = " + Sys_Convert_Long_To_String(lst_combat_type.get(combat_index)))
      call Sys_Debug_Print("Enemy Analysis", "    - Result = " + Sys_Convert_Long_To_String(lst_combat_result.get(combat_index)))
      call Sys_Debug_Print("Enemy Analysis", "    - Point Value = " + Sys_Convert_Long_To_String(lst_combat_point_value.get(combat_index)))
      call Sys_Debug_Print("Enemy Analysis", "    - Colony Lost = " + Sys_Convert_Long_To_String(lst_combat_colony_lost.get(combat_index)))
      call Sys_Debug_Print("Enemy Analysis", "    - Plr1 = " + plr1_name)
      call Sys_Debug_Print("Enemy Analysis", "    - Plr2 = " + plr2_name)
      call Sys_Debug_Print("Enemy Analysis", "    - Plr3 = " + plr3_name)
      call Sys_Debug_Print("Enemy Analysis", "    - Plr4 = " + plr4_name)
    endfor
  endif

  return TRUE
end

//------------------------------------------------------------------------